]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR lto/53831 (Virtuals missing in LTO symtab)
authorJan Hubicka <jh@suse.cz>
Sat, 6 Oct 2012 17:30:42 +0000 (19:30 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 6 Oct 2012 17:30:42 +0000 (17:30 +0000)
PR lto/53831
PR lto/54776
* lto-streamer-out.c (produce_symtab): Cleanup; drop v1 API hack.

From-SVN: r192166

gcc/ChangeLog
gcc/lto-streamer-out.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C [new file with mode: 0644]

index 4eca5bf49e3b922ca76b122b2d416a2c79ee7b6b..826729bbee92571a96fb2f7cd318a3d744b07729 100644 (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
index afe49517eb1f16c69c5d29e2825b98d15af6af7b..083db74f911600833b40014fcc1d9227e5af4995 100644 (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)
+      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);
index 88f3a516a329cb18d998116a9d5eb5b72b1200bb..1a28cda577cd8fc0733547c030061d741d500993 100644 (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.
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 (file)
index 0000000..f79dfae
--- /dev/null
@@ -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;
+}