re PR c++/79687 (Wrong code with pointer-to-member)
authorMarek Polacek <polacek@redhat.com>
Thu, 9 Mar 2017 16:36:37 +0000 (16:36 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 9 Mar 2017 16:36:37 +0000 (16:36 +0000)
PR c++/79687
* init.c (constant_value_1): Break if the variable has a dynamic
initializer.

* g++.dg/expr/ptrmem8.C: New test.
* g++.dg/expr/ptrmem9.C: New test.

From-SVN: r246008

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/ptrmem8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/expr/ptrmem9.C [new file with mode: 0644]

index caf0322972ff64a56c6ea079304c2508675e5bcb..4f4691a0393a20155dade6c862070b44cff3e640 100644 (file)
@@ -4,6 +4,10 @@
        * tree.c (strip_typedefs): Skip the attribute handling if T is
        a variant type which hasn't been updated yet.
 
+       PR c++/79687 - wrong code with pointer-to-member
+       * init.c (constant_value_1): Break if the variable has a dynamic
+       initializer.
+
 2017-03-08  Jason Merrill  <jason@redhat.com>
 
        PR c++/79797 - ICE with self-reference in array DMI.
index e4f038912286a05e28410721bfa03f5f735d04cd..18043e8c57fcbca42050301f3e73acf0df39a5b3 100644 (file)
@@ -2203,6 +2203,13 @@ constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p)
       if (TREE_CODE (init) == CONSTRUCTOR
          && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
        break;
+      /* If the variable has a dynamic initializer, don't use its
+        DECL_INITIAL which doesn't reflect the real value.  */
+      if (VAR_P (decl)
+         && TREE_STATIC (decl)
+         && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+         && DECL_NONTRIVIALLY_INITIALIZED_P (decl))
+       break;
       decl = unshare_expr (init);
     }
   return decl;
index 5050929f1a88504b997c2ca8e8cff48fa20605a1..cad76f21eed079e21a1a8eaf42f18e2c5890556e 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-09  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/79687
+       * g++.dg/expr/ptrmem8.C: New test.
+       * g++.dg/expr/ptrmem9.C: New test.
+
 2017-03-09  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/79977
diff --git a/gcc/testsuite/g++.dg/expr/ptrmem8.C b/gcc/testsuite/g++.dg/expr/ptrmem8.C
new file mode 100644 (file)
index 0000000..c5a766a
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/79687
+// { dg-do run }
+
+struct A
+{
+  char c;
+};
+
+int main()
+{
+  char A::* p = &A::c;
+  static char A::* const q = p;
+  A a;
+  return &(a.*q) - &a.c;
+}
diff --git a/gcc/testsuite/g++.dg/expr/ptrmem9.C b/gcc/testsuite/g++.dg/expr/ptrmem9.C
new file mode 100644 (file)
index 0000000..32ce777
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/79687
+// { dg-do run }
+
+struct A
+{
+  char c;
+};
+
+int main()
+{
+  static char A::* p1 = &A::c;
+  char A::* const q1 = p1;
+
+  char A::* p2 = &A::c;
+  static char A::* const q2 = p2;
+
+  A a;
+  return (&(a.*q1) - &a.c) || (&(a.*q2) - &a.c);
+}