re PR lto/53831 (Virtuals missing in LTO symtab)

PR lto/53831
	PR lto/54776
	* lto-streamer-out.c (produce_symtab): Cleanup; drop v1 API hack.

From-SVN: r192166
This commit is contained in:
Jan Hubicka 2012-10-06 19:30:42 +02:00 committed by Jan Hubicka
parent f16dd82295
commit c295453808
4 changed files with 81 additions and 69 deletions

View File

@ -1,3 +1,9 @@
2012-10-06 Jan Hubicka <jh@suse.cz>
PR lto/53831
PR lto/54776
* lto-streamer-out.c (produce_symtab): Cleanup; drop v1 API hack.
2012-10-06 Dehao Chen <dehao@google.com>
PR debug/54826

View File

@ -1285,11 +1285,9 @@ produce_symtab (struct output_block *ob)
struct streamer_tree_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
struct pointer_set_t *seen;
struct cgraph_node *node;
struct varpool_node *vnode;
struct lto_output_stream stream;
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
int i;
lto_symtab_encoder_iterator lsei;
lto_begin_section (section_name, false);
free (section_name);
@ -1297,78 +1295,26 @@ produce_symtab (struct output_block *ob)
seen = pointer_set_create ();
memset (&stream, 0, sizeof (stream));
/* Write all functions.
First write all defined functions and then write all used functions.
This is done so only to handle duplicated symbols in cgraph. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
/* Write the symbol table.
First write everything defined and then all declarations.
This is neccesary to handle cases where we have duplicated symbols. */
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
continue;
node = cgraph (lto_symtab_encoder_deref (encoder, i));
if (DECL_EXTERNAL (node->symbol.decl))
continue;
if (DECL_COMDAT (node->symbol.decl)
&& cgraph_comdat_can_be_unshared_p (node))
continue;
if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
continue;
write_symbol (cache, &stream, node->symbol.decl, seen, false);
}
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
continue;
node = cgraph (lto_symtab_encoder_deref (encoder, i));
if (!DECL_EXTERNAL (node->symbol.decl))
continue;
/* We keep around unused extern inlines in order to be able to inline
them indirectly or via vtables. Do not output them to symbol
table: they end up being undefined and just consume space. */
if (!node->symbol.address_taken && !node->callers)
continue;
if (DECL_COMDAT (node->symbol.decl)
&& cgraph_comdat_can_be_unshared_p (node))
continue;
if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
continue;
write_symbol (cache, &stream, node->symbol.decl, seen, false);
}
symtab_node node = lsei_node (lsei);
/* Write all variables. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
if (!symtab_real_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl))
continue;
vnode = varpool (lto_symtab_encoder_deref (encoder, i));
if (DECL_EXTERNAL (vnode->symbol.decl))
continue;
/* COMDAT virtual tables can be unshared. Do not declare them
in the LTO symbol table to prevent linker from forcing them
into the output. */
if (DECL_COMDAT (vnode->symbol.decl)
&& !vnode->symbol.force_output
&& vnode->finalized
&& DECL_VIRTUAL_P (vnode->symbol.decl))
continue;
if (vnode->alias && !vnode->alias_of)
continue;
write_symbol (cache, &stream, vnode->symbol.decl, seen, false);
write_symbol (cache, &stream, node->symbol.decl, seen, false);
}
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
symtab_node node = lsei_node (lsei);
if (!symtab_real_symbol_p (node) || !DECL_EXTERNAL (node->symbol.decl))
continue;
vnode = varpool (lto_symtab_encoder_deref (encoder, i));
if (!DECL_EXTERNAL (vnode->symbol.decl))
continue;
if (DECL_COMDAT (vnode->symbol.decl)
&& !vnode->symbol.force_output
&& vnode->finalized
&& DECL_VIRTUAL_P (vnode->symbol.decl))
continue;
if (vnode->alias && !vnode->alias_of)
continue;
write_symbol (cache, &stream, vnode->symbol.decl, seen, false);
write_symbol (cache, &stream, node->symbol.decl, seen, false);
}
lto_write_stream (&stream);

View File

@ -3,6 +3,12 @@
PR fortran/54832
* gfortran.dg/typebound_operator_17.f90: New.
2012-10-06 Jan Hubicka <jh@suse.cz>
PR lto/53831
PR lto/54776
* g++.dg/lto/v1-plugin-api-not-supported.C: New testcase.
2012-10-06 Jan Hubicka <jh@suse.cz>
* gcc.dg/lto/resolutions_0.c: New testcase.

View File

@ -0,0 +1,54 @@
// { dg-lto-do run }
// { dg-require-linker-plugin "" }
// { dg-lto-options {{-O2 -fuse-linker-plugin -fno-early-inlining}}
extern "C" void abort (void);
extern "C" void linker_error ();
class A
{
public:
int data;
virtual int foo (int i)
{
return i + 1;
}
};
class B : public A
{
public:
virtual int foo (int i)
{
return i + 2;
}
};
class C : public A
{
public:
virtual int foo (int i)
{
linker_error ();
return i + 3;
}
};
static int middleman (class A *obj, int i)
{
return obj->foo (i);
}
int __attribute__ ((noinline,noclone)) get_input(void)
{
return 1;
}
int main (int argc, char *argv[])
{
class B b;
if (middleman (&b, get_input ()) != 3)
abort ();
return 0;
}