From c295453808f7ccf94f440ceec7feb51de21b3e35 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 6 Oct 2012 19:30:42 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++ gcc/lto-streamer-out.c | 82 ++++--------------- gcc/testsuite/ChangeLog | 6 ++ .../lto/v1-plugin-api-not-supported_0.C | 54 ++++++++++++ 4 files changed, 80 insertions(+), 68 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4eca5bf49e3b..826729bbee92 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-10-06 Jan Hubicka + + PR lto/53831 + PR lto/54776 + * lto-streamer-out.c (produce_symtab): Cleanup; drop v1 API hack. + 2012-10-06 Dehao Chen PR debug/54826 diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index afe49517eb1f..083db74f9116 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -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) + symtab_node node = lsei_node (lsei); + + if (!symtab_real_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl)) continue; 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))) - 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))) - 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)) + if (!symtab_real_symbol_p (node) || !DECL_EXTERNAL (node->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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 88f3a516a329..1a28cda577cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,12 @@ PR fortran/54832 * gfortran.dg/typebound_operator_17.f90: New. +2012-10-06 Jan Hubicka + + PR lto/53831 + PR lto/54776 + * g++.dg/lto/v1-plugin-api-not-supported.C: New testcase. + 2012-10-06 Jan Hubicka * gcc.dg/lto/resolutions_0.c: New testcase. diff --git a/gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C b/gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C new file mode 100644 index 000000000000..f79dfae5c6f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C @@ -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; +}