]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR ipa/59176 (ICE edge points to wrong declaration / verify_cgraph_node failed)
authorMartin Jambor <mjambor@suse.cz>
Fri, 21 Mar 2014 12:59:35 +0000 (13:59 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 21 Mar 2014 12:59:35 +0000 (13:59 +0100)
2014-03-21  Martin Jambor  <mjambor@suse.cz>

PR ipa/59176
* cgraph.h (symtab_node): New flag body_removed.
* ipa.c (symtab_remove_unreachable_nodes): Set body_removed flag
when removing bodies.
* symtab.c (dump_symtab_base): Dump body_removed flag.
* cgraph.c (verify_edge_corresponds_to_fndecl): Skip nodes which
had their bodies removed.

testsuite/
        * g++.dg/torture/pr59176.C: New test.

From-SVN: r208748

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa.c
gcc/symtab.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr59176.C [new file with mode: 0644]

index c56a5b7df52588e5b95c78c57d16a4150b417560..57a7688de32f18563e50fadb4461b490c0dd5b14 100644 (file)
@@ -1,3 +1,13 @@
+2014-03-21  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/59176
+       * cgraph.h (symtab_node): New flag body_removed.
+       * ipa.c (symtab_remove_unreachable_nodes): Set body_removed flag
+       when removing bodies.
+       * symtab.c (dump_symtab_base): Dump body_removed flag.
+       * cgraph.c (verify_edge_corresponds_to_fndecl): Skip nodes which
+       had their bodies removed.
+
 2014-03-21  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/60419
index 577352faa9d934f36e3dc14aa5e87faa6e88df30..abfd63c9955c2cf064caacad47f75eea4b17a573 100644 (file)
@@ -2604,8 +2604,13 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
   node = cgraph_get_node (decl);
 
   /* We do not know if a node from a different partition is an alias or what it
-     aliases and therefore cannot do the former_clone_of check reliably.  */
-  if (!node || node->in_other_partition || e->callee->in_other_partition)
+     aliases and therefore cannot do the former_clone_of check reliably.  When
+     body_removed is set, we have lost all information about what was alias or
+     thunk of and also cannot proceed.  */
+  if (!node
+      || node->body_removed
+      || node->in_other_partition
+      || e->callee->in_other_partition)
     return false;
   node = cgraph_function_or_thunk_node (node, NULL);
 
index 32b1ee17fa3e042fb68787205ae363b84f4a78d9..59d9ce66845f1dec91d29aa3b19effbc596133e2 100644 (file)
@@ -91,7 +91,9 @@ public:
   unsigned forced_by_abi : 1;
   /* True when the name is known to be unique and thus it does not need mangling.  */
   unsigned unique_name : 1;
-
+  /* True when body and other characteristics have been removed by
+     symtab_remove_unreachable_nodes. */
+  unsigned body_removed : 1;
 
   /*** WHOPR Partitioning flags.
        These flags are used at ltrans stage when only part of the callgraph is
index 164de0dc9dfe273c45ce411bafad86f0bdb15f7d..d23031286f2f07a245b00173fe38daafb2e9d11f 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -484,6 +484,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
            {
              if (file)
                fprintf (file, " %s", node->name ());
+             node->body_removed = true;
              node->analyzed = false;
              node->definition = false;
              node->cpp_implicit_alias = false;
@@ -543,6 +544,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
                fprintf (file, " %s", vnode->name ());
              changed = true;
            }
+         vnode->body_removed = true;
          vnode->definition = false;
          vnode->analyzed = false;
          vnode->aux = NULL;
index 2d6f665b120fb31c8b9342b7fe91fd9c1a0e6acb..4db4870fa4e5175ae6b537cc7bcb9bb0ad20a294 100644 (file)
@@ -601,6 +601,8 @@ dump_symtab_base (FILE *f, symtab_node *node)
             ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
                                     (node->alias_target))
             : IDENTIFIER_POINTER (node->alias_target));
+  if (node->body_removed)
+    fprintf (f, "\n  Body removed by symtab_remove_unreachable_nodes");
   fprintf (f, "\n  Visibility:");
   if (node->in_other_partition)
     fprintf (f, " in_other_partition");
index 581efab5981227632823d2960ca10b8f3791f4c6..9740621934c6d9cf0d0bf9fe322069ffad001ecf 100644 (file)
@@ -1,3 +1,8 @@
+2014-03-21  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/59176
+        * g++.dg/torture/pr59176.C: New test.
+
 2014-03-21  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/60419
diff --git a/gcc/testsuite/g++.dg/ipa/pr59176.C b/gcc/testsuite/g++.dg/ipa/pr59176.C
new file mode 100644 (file)
index 0000000..d576bc3
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+template <class> class A {
+protected:
+  void m_fn2();
+  ~A() { m_fn2(); }
+  virtual void m_fn1();
+};
+
+class D : A<int> {};
+template <class Key> void A<Key>::m_fn2() {
+  m_fn1();
+  m_fn1();
+  m_fn1();
+}
+
+#pragma interface
+class B {
+  D m_cellsAlreadyProcessed;
+  D m_cellsNotToProcess;
+
+public:
+  virtual ~B() {}
+  void m_fn1();
+};
+
+class C {
+  unsigned long m_fn1();
+  B m_fn2();
+  unsigned long m_fn3();
+};
+unsigned long C::m_fn1() {
+CellHierarchy:
+  m_fn2().m_fn1();
+}
+
+unsigned long C::m_fn3() {
+CellHierarchy:
+  m_fn2().m_fn1();
+}