Hi!

The local pure const pass notices the static ctor is looping const,
so sets TREE_READONLY and DECL_LOOPING_CONST_OR_PURE_P and does not
clear DECL_STATIC_CONSTRUCTOR bit because it is looping.
Then the ipa pure const pass notices the static ctor is non-looping const,
clears DECL_LOOPING_CONST_OR_PURE_P and DECL_STATIC_CONSTRUCTOR bit,
but because it has been TREE_READONLY already, it doesn't set
TODO_remove_functions from the pass and ipa-comdat pass assumes that
unreachable cgraph nodes have been pruned.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2016-12-12  Jakub Jelinek  <ja...@redhat.com>

        PR ipa/77905
        * ipa-pure-const.c (cdtor_p): Return true for
        DECL_STATIC_{CON,DE}STRUCTOR even when it is
        DECL_LOOPING_CONST_OR_PURE_P.

        * g++.dg/ipa/pr77905.C: New test.

--- gcc/ipa-pure-const.c.jj     2016-09-02 19:09:33.000000000 +0200
+++ gcc/ipa-pure-const.c        2016-12-12 11:51:24.808518093 +0100
@@ -1195,7 +1195,8 @@ static bool
 cdtor_p (cgraph_node *n, void *)
 {
   if (DECL_STATIC_CONSTRUCTOR (n->decl) || DECL_STATIC_DESTRUCTOR (n->decl))
-    return !TREE_READONLY (n->decl) && !DECL_PURE_P (n->decl);
+    return ((!TREE_READONLY (n->decl) && !DECL_PURE_P (n->decl))
+           || DECL_LOOPING_CONST_OR_PURE_P (n->decl));
   return false;
 }
 
--- gcc/testsuite/g++.dg/ipa/pr77905.C.jj       2016-12-12 11:53:42.645770248 
+0100
+++ gcc/testsuite/g++.dg/ipa/pr77905.C  2016-12-12 11:53:35.000000000 +0100
@@ -0,0 +1,21 @@
+// PR ipa/77905
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct A {
+  A(int);
+};
+struct B : A {
+  B();
+} A;
+struct C : virtual A {
+  C(int);
+};
+A::A(int x) {
+  if (x)
+    A(0);
+}
+
+B::B() : A(1) {}
+
+C::C(int) : A(1) {}

        Jakub

Reply via email to