]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/42386 (ICE in ipcp_iterate_stage, at ipa-cp.c:766)
authorJakub Jelinek <jakub@redhat.com>
Thu, 17 Dec 2009 19:29:48 +0000 (20:29 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 17 Dec 2009 19:29:48 +0000 (20:29 +0100)
PR c++/42386
* ipa.c (function_and_variable_visibility): Clear same_comdat_group
links of DECL_EXTERNAL nodes.

* g++.dg/opt/dtor3.C: New test.

From-SVN: r155321

gcc/ChangeLog
gcc/ipa.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/dtor3.C [new file with mode: 0644]

index b7338c5d5ab316290b5ee7b5062e0b47a8f5c41c..90dc2c8088b7fd7ebe0da45c47b0f8e5b7075a07 100644 (file)
@@ -1,3 +1,9 @@
+2009-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/42386
+       * ipa.c (function_and_variable_visibility): Clear same_comdat_group
+       links of DECL_EXTERNAL nodes.
+
 2009-12-17  Sandra Loosemore  <sandra@codesourcery.com>
 
        * doc/rtl.texi (Vector Operations): Clarify vec_select result mode.
index b1844db256e3b4c2a981717e93b0e8acfe55129a..1230448ecbfe0ffa68cff5de2b0afcf7e37c6cd3 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -370,6 +370,23 @@ function_and_variable_visibility (bool whole_program)
         happy.  Clear the flag here to avoid confusion in middle-end.  */
       if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
         DECL_COMDAT (node->decl) = 0;
+      /* For external decls stop tracking same_comdat_group, it doesn't matter
+        what comdat group they are in when they won't be emitted in this TU,
+        and simplifies later passes.  */
+      if (node->same_comdat_group && DECL_EXTERNAL (node->decl))
+       {
+         struct cgraph_node *n = node, *next;
+         do
+           {
+             /* If at least one of same comdat group functions is external,
+                all of them have to be, otherwise it is a front-end bug.  */
+             gcc_assert (DECL_EXTERNAL (n->decl));
+             next = n->same_comdat_group;
+             n->same_comdat_group = NULL;
+             n = next;
+           }
+         while (n != node);
+       }
       gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
                  || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
       if (cgraph_externally_visible_p (node, whole_program))
index f6ee73516deba57bb2ec6b750760637d8338ff10..a8ee952212a0f16f504def8878e6bffd1bdec48f 100644 (file)
@@ -1,3 +1,8 @@
+2009-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/42386
+       * g++.dg/opt/dtor3.C: New test.
+
 2009-12-17  Arnaud Charlet  <charlet@adacore.com>
 
        * ada/acats/run_all.sh: Strip comments from norun.lst
diff --git a/gcc/testsuite/g++.dg/opt/dtor3.C b/gcc/testsuite/g++.dg/opt/dtor3.C
new file mode 100644 (file)
index 0000000..2d93098
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/42386
+// { dg-do compile }
+// { dg-options "-O2" }
+# 1 "A.h" 1
+#pragma interface
+struct D { virtual bool d () const; };
+struct E { virtual ~E (); virtual void *e () const = 0; };
+struct A : public D, public E { ~A () {} };
+# 5 "dtor3.C" 1
+struct F : public A { void *f () const; void *e () const; };
+void *F::e () const { return __null; }