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>
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.
......
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
......
// 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
#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,8 +609,32 @@ 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
......@@ -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)
{
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);
/* 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)
{
fclose (stream);
return 0;
}
}
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