Commit 4e92c31f by Jason Merrill Committed by Jason Merrill

re PR c++/51910 (-frepo linking failure)

	PR c++/51910
	* tlink.c (demangled_hash_entry): Change mangled to a VEC.
	(demangle_new_symbols): Fill it.
	(scan_linker_output): Walk it.
	(start_tweaking): Split out from scan_linker_output.
	(maybe_tweak): Update sym->chosen.
	* Makefile.in (COLLECT2_OBJS): Add vec.o and gcc-none.o

From-SVN: r184127
parent bd0ba05d
2012-02-10 Jason Merrill <jason@redhat.com>
PR c++/51910
* tlink.c (demangled_hash_entry): Change mangled to a VEC.
(demangle_new_symbols): Fill it.
(scan_linker_output): Walk it.
(start_tweaking): Split out from scan_linker_output.
(maybe_tweak): Update sym->chosen.
* Makefile.in (COLLECT2_OBJS): Add vec.o and gcc-none.o
2012-02-11 Jakub Jelinek <jakub@redhat.com> 2012-02-11 Jakub Jelinek <jakub@redhat.com>
PR debug/52132 PR debug/52132
......
...@@ -1946,7 +1946,7 @@ gcc-ranlib.c: gcc-ar.c ...@@ -1946,7 +1946,7 @@ gcc-ranlib.c: gcc-ar.c
gcc-nm.c: gcc-ar.c gcc-nm.c: gcc-ar.c
cp $^ $@ cp $^ $@
COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o
COLLECT2_LIBS = @COLLECT2_LIBS@ COLLECT2_LIBS = @COLLECT2_LIBS@
collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
# Don't try modifying collect2 (aka ld) in place--it might be linking this. # Don't try modifying collect2 (aka ld) in place--it might be linking this.
......
2012-02-10 Jason Merrill <jason@redhat.com>
PR c++/51910
* g++.dg/template/repo10.C: New.
2012-02-11 Jakub Jelinek <jakub@redhat.com> 2012-02-11 Jakub Jelinek <jakub@redhat.com>
PR debug/52132 PR debug/52132
......
// PR c++/51910
// { dg-options -frepo }
// { dg-require-host-local "" }
// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
// { dg-final cleanup-repo-files }
template<typename T>
struct Foo
{
virtual ~Foo() { }
};
int main( int, char*[] )
{
Foo<int> test;
}
...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "collect2.h" #include "collect2.h"
#include "filenames.h" #include "filenames.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "vec.h"
/* TARGET_64BIT may be defined to use driver specific functionality. */ /* TARGET_64BIT may be defined to use driver specific functionality. */
#undef TARGET_64BIT #undef TARGET_64BIT
...@@ -67,10 +68,14 @@ typedef struct file_hash_entry ...@@ -67,10 +68,14 @@ typedef struct file_hash_entry
int tweaking; int tweaking;
} file; } file;
typedef const char *str;
DEF_VEC_P(str);
DEF_VEC_ALLOC_P(str,heap);
typedef struct demangled_hash_entry typedef struct demangled_hash_entry
{ {
const char *key; const char *key;
const char *mangled; VEC(str,heap) *mangled;
} demangled; } demangled;
/* Hash and comparison functions for these hash tables. */ /* Hash and comparison functions for these hash tables. */
...@@ -435,9 +440,15 @@ maybe_tweak (char *line, file *f) ...@@ -435,9 +440,15 @@ maybe_tweak (char *line, file *f)
sym->tweaked = 1; sym->tweaked = 1;
if (line[0] == 'O') if (line[0] == 'O')
{
line[0] = 'C'; line[0] = 'C';
sym->chosen = 1;
}
else else
{
line[0] = 'O'; line[0] = 'O';
sym->chosen = 0;
}
} }
} }
...@@ -598,10 +609,34 @@ demangle_new_symbols (void) ...@@ -598,10 +609,34 @@ demangle_new_symbols (void)
continue; continue;
dem = demangled_hash_lookup (p, true); dem = demangled_hash_lookup (p, true);
dem->mangled = sym->key; VEC_safe_push (str, heap, dem->mangled, sym->key);
} }
} }
/* We want to tweak symbol SYM. Return true if all is well, false on
error. */
static bool
start_tweaking (symbol *sym)
{
if (sym && sym->tweaked)
{
error ("'%s' was assigned to '%s', but was not defined "
"during recompilation, or vice versa",
sym->key, sym->file->key);
return 0;
}
if (sym && !sym->tweaking)
{
if (tlink_verbose >= 2)
fprintf (stderr, _("collect: tweaking %s in %s\n"),
sym->key, sym->file->key);
sym->tweaking = 1;
file_push (sym->file);
}
return true;
}
/* Step through the output of the linker, in the file named FNAME, and /* Step through the output of the linker, in the file named FNAME, and
adjust the settings for each symbol encountered. */ adjust the settings for each symbol encountered. */
...@@ -616,8 +651,11 @@ scan_linker_output (const char *fname) ...@@ -616,8 +651,11 @@ scan_linker_output (const char *fname)
{ {
char *p = line, *q; char *p = line, *q;
symbol *sym; symbol *sym;
demangled *dem = 0;
int end; int end;
int ok = 0; int ok = 0;
unsigned ix;
str s;
/* On darwin9, we might have to skip " in " lines as well. */ /* On darwin9, we might have to skip " in " lines as well. */
if (skip_next_in_line if (skip_next_in_line
...@@ -662,7 +700,6 @@ scan_linker_output (const char *fname) ...@@ -662,7 +700,6 @@ scan_linker_output (const char *fname)
/* Try a mangled name in quotes. */ /* Try a mangled name in quotes. */
{ {
char *oldq = q + 1; char *oldq = q + 1;
demangled *dem = 0;
q = 0; q = 0;
/* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */ /* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */
...@@ -718,9 +755,7 @@ scan_linker_output (const char *fname) ...@@ -718,9 +755,7 @@ scan_linker_output (const char *fname)
{ {
*q = 0; *q = 0;
dem = demangled_hash_lookup (p, false); dem = demangled_hash_lookup (p, false);
if (dem) if (!dem)
sym = symbol_hash_lookup (dem->mangled, false);
else
{ {
if (!strncmp (p, USER_LABEL_PREFIX, if (!strncmp (p, USER_LABEL_PREFIX,
strlen (USER_LABEL_PREFIX))) strlen (USER_LABEL_PREFIX)))
...@@ -730,24 +765,43 @@ scan_linker_output (const char *fname) ...@@ -730,24 +765,43 @@ scan_linker_output (const char *fname)
} }
} }
if (sym && sym->tweaked) if (dem)
{ {
error ("'%s' was assigned to '%s', but was not defined " /* We found a demangled name. If this is the name of a
"during recompilation, or vice versa", constructor or destructor, there can be several mangled names
sym->key, sym->file->key); that match it, so choose or unchoose all of them. If some are
fclose (stream); chosen and some not, leave the later ones that don't match
return 0; alone for now; either this will cause the link to suceed, or
on the next attempt we will switch all of them the other way
and that will cause it to succeed. */
int chosen = 0;
int len = VEC_length (str, dem->mangled);
ok = true;
FOR_EACH_VEC_ELT (str, dem->mangled, ix, s)
{
sym = symbol_hash_lookup (s, false);
if (ix == 0)
chosen = sym->chosen;
else if (sym->chosen != chosen)
/* Mismatch. */
continue;
/* Avoid an error about re-tweaking when we guess wrong in
the case of mismatch. */
if (len > 1)
sym->tweaked = false;
ok = start_tweaking (sym);
} }
if (sym && !sym->tweaking)
{
if (tlink_verbose >= 2)
fprintf (stderr, _("collect: tweaking %s in %s\n"),
sym->key, sym->file->key);
sym->tweaking = 1;
file_push (sym->file);
} }
else
ok = start_tweaking (sym);
obstack_free (&temporary_obstack, temporary_firstobj); obstack_free (&temporary_obstack, temporary_firstobj);
if (!ok)
{
fclose (stream);
return 0;
}
} }
fclose (stream); fclose (stream);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment