aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2012-10-06 19:30:42 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2012-10-06 17:30:42 +0000
commitc295453808f7ccf94f440ceec7feb51de21b3e35 (patch)
tree3650d070f4c1544ff3a261eeb937f523f564f45c
parentf16dd8229532dcf804ad6735136cdb4c9ad268b6 (diff)
downloadgcc-c295453808f7ccf94f440ceec7feb51de21b3e35.zip
gcc-c295453808f7ccf94f440ceec7feb51de21b3e35.tar.gz
gcc-c295453808f7ccf94f440ceec7feb51de21b3e35.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lto-streamer-out.c82
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C54
4 files changed, 80 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4eca5bf..826729b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index afe4951..083db74 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 88f3a51..1a28cda 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -5,6 +5,12 @@
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.
2012-10-06 Janus Weil <janus@gcc.gnu.org>
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 0000000..f79dfae
--- /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;
+}