aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2017-03-09 16:36:37 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2017-03-09 16:36:37 +0000
commit6443c7c0e5e1b348ff5841463e3c3828b3036e30 (patch)
tree22baa88c105d2a2309c26e858445dfc6186a00fd /gcc
parentd721dc3c4bb4a29f6c2cee5be88710a1b107e2f2 (diff)
downloadgcc-6443c7c0e5e1b348ff5841463e3c3828b3036e30.zip
gcc-6443c7c0e5e1b348ff5841463e3c3828b3036e30.tar.gz
gcc-6443c7c0e5e1b348ff5841463e3c3828b3036e30.tar.bz2
re PR c++/79687 (Wrong code with pointer-to-member)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/init.c7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/expr/ptrmem8.C15
-rw-r--r--gcc/testsuite/g++.dg/expr/ptrmem9.C19
5 files changed, 51 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index caf0322..4f4691a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e4f0389..18043e8 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5050929..cad76f2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c5a766a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/ptrmem8.C
@@ -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
index 0000000..32ce777
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/ptrmem9.C
@@ -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);
+}