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
This commit is contained in:
parent
bd0ba05d4c
commit
4e92c31f3a
5 changed files with 108 additions and 23 deletions
|
@ -1,3 +1,13 @@
|
|||
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>
|
||||
|
||||
PR debug/52132
|
||||
|
|
|
@ -1946,7 +1946,7 @@ gcc-ranlib.c: gcc-ar.c
|
|||
gcc-nm.c: gcc-ar.c
|
||||
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$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
|
||||
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
PR debug/52132
|
||||
|
|
16
gcc/testsuite/g++.dg/template/repo10.C
Normal file
16
gcc/testsuite/g++.dg/template/repo10.C
Normal file
|
@ -0,0 +1,16 @@
|
|||
// 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;
|
||||
}
|
98
gcc/tlink.c
98
gcc/tlink.c
|
@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "collect2.h"
|
||||
#include "filenames.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "vec.h"
|
||||
|
||||
/* TARGET_64BIT may be defined to use driver specific functionality. */
|
||||
#undef TARGET_64BIT
|
||||
|
@ -67,10 +68,14 @@ typedef struct file_hash_entry
|
|||
int tweaking;
|
||||
} file;
|
||||
|
||||
typedef const char *str;
|
||||
DEF_VEC_P(str);
|
||||
DEF_VEC_ALLOC_P(str,heap);
|
||||
|
||||
typedef struct demangled_hash_entry
|
||||
{
|
||||
const char *key;
|
||||
const char *mangled;
|
||||
VEC(str,heap) *mangled;
|
||||
} demangled;
|
||||
|
||||
/* Hash and comparison functions for these hash tables. */
|
||||
|
@ -435,9 +440,15 @@ maybe_tweak (char *line, file *f)
|
|||
sym->tweaked = 1;
|
||||
|
||||
if (line[0] == 'O')
|
||||
line[0] = 'C';
|
||||
{
|
||||
line[0] = 'C';
|
||||
sym->chosen = 1;
|
||||
}
|
||||
else
|
||||
line[0] = 'O';
|
||||
{
|
||||
line[0] = 'O';
|
||||
sym->chosen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,10 +609,34 @@ demangle_new_symbols (void)
|
|||
continue;
|
||||
|
||||
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
|
||||
adjust the settings for each symbol encountered. */
|
||||
|
||||
|
@ -616,8 +651,11 @@ scan_linker_output (const char *fname)
|
|||
{
|
||||
char *p = line, *q;
|
||||
symbol *sym;
|
||||
demangled *dem = 0;
|
||||
int end;
|
||||
int ok = 0;
|
||||
unsigned ix;
|
||||
str s;
|
||||
|
||||
/* On darwin9, we might have to skip " in " lines as well. */
|
||||
if (skip_next_in_line
|
||||
|
@ -662,7 +700,6 @@ scan_linker_output (const char *fname)
|
|||
/* Try a mangled name in quotes. */
|
||||
{
|
||||
char *oldq = q + 1;
|
||||
demangled *dem = 0;
|
||||
q = 0;
|
||||
|
||||
/* On darwin9, we look for "foo" referenced from:\n\(.* in .*\n\)* */
|
||||
|
@ -718,9 +755,7 @@ scan_linker_output (const char *fname)
|
|||
{
|
||||
*q = 0;
|
||||
dem = demangled_hash_lookup (p, false);
|
||||
if (dem)
|
||||
sym = symbol_hash_lookup (dem->mangled, false);
|
||||
else
|
||||
if (!dem)
|
||||
{
|
||||
if (!strncmp (p, USER_LABEL_PREFIX,
|
||||
strlen (USER_LABEL_PREFIX)))
|
||||
|
@ -730,24 +765,43 @@ scan_linker_output (const char *fname)
|
|||
}
|
||||
}
|
||||
|
||||
if (sym && sym->tweaked)
|
||||
if (dem)
|
||||
{
|
||||
/* We found a demangled name. If this is the name of a
|
||||
constructor or destructor, there can be several mangled names
|
||||
that match it, so choose or unchoose all of them. If some are
|
||||
chosen and some not, leave the later ones that don't match
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
ok = start_tweaking (sym);
|
||||
|
||||
obstack_free (&temporary_obstack, temporary_firstobj);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
error ("'%s' was assigned to '%s', but was not defined "
|
||||
"during recompilation, or vice versa",
|
||||
sym->key, sym->file->key);
|
||||
fclose (stream);
|
||||
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);
|
||||
}
|
||||
|
||||
obstack_free (&temporary_obstack, temporary_firstobj);
|
||||
}
|
||||
|
||||
fclose (stream);
|
||||
|
|
Loading…
Add table
Reference in a new issue