Commit c2954538 by Jan Hubicka Committed by Jan Hubicka

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
parent f16dd822
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> 2012-10-06 Dehao Chen <dehao@google.com>
PR debug/54826 PR debug/54826
......
...@@ -1285,11 +1285,9 @@ produce_symtab (struct output_block *ob) ...@@ -1285,11 +1285,9 @@ produce_symtab (struct output_block *ob)
struct streamer_tree_cache_d *cache = ob->writer_cache; struct streamer_tree_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL); char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
struct pointer_set_t *seen; struct pointer_set_t *seen;
struct cgraph_node *node;
struct varpool_node *vnode;
struct lto_output_stream stream; struct lto_output_stream stream;
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder; lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
int i; lto_symtab_encoder_iterator lsei;
lto_begin_section (section_name, false); lto_begin_section (section_name, false);
free (section_name); free (section_name);
...@@ -1297,78 +1295,26 @@ produce_symtab (struct output_block *ob) ...@@ -1297,78 +1295,26 @@ produce_symtab (struct output_block *ob)
seen = pointer_set_create (); seen = pointer_set_create ();
memset (&stream, 0, sizeof (stream)); memset (&stream, 0, sizeof (stream));
/* Write all functions. /* Write the symbol table.
First write all defined functions and then write all used functions. First write everything defined and then all declarations.
This is done so only to handle duplicated symbols in cgraph. */ This is neccesary to handle cases where we have duplicated symbols. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++) for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{ {
if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i))) symtab_node node = lsei_node (lsei);
continue;
node = cgraph (lto_symtab_encoder_deref (encoder, i)); if (!symtab_real_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl))
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; continue;
write_symbol (cache, &stream, node->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_function_p (lto_symtab_encoder_deref (encoder, i))) symtab_node node = lsei_node (lsei);
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);
}
/* Write all variables. */ if (!symtab_real_symbol_p (node) || !DECL_EXTERNAL (node->symbol.decl))
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
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);
}
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
continue;
vnode = varpool (lto_symtab_encoder_deref (encoder, i));
if (!DECL_EXTERNAL (vnode->symbol.decl))
continue; continue;
if (DECL_COMDAT (vnode->symbol.decl) write_symbol (cache, &stream, node->symbol.decl, seen, false);
&& !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);
} }
lto_write_stream (&stream); lto_write_stream (&stream);
......
...@@ -5,6 +5,12 @@ ...@@ -5,6 +5,12 @@
2012-10-06 Jan Hubicka <jh@suse.cz> 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. * gcc.dg/lto/resolutions_0.c: New testcase.
2012-10-06 Janus Weil <janus@gcc.gnu.org> 2012-10-06 Janus Weil <janus@gcc.gnu.org>
......
// { 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;
}
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