From 6443c7c0e5e1b348ff5841463e3c3828b3036e30 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 9 Mar 2017 16:36:37 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/init.c | 7 +++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/expr/ptrmem8.C | 15 +++++++++++++++ gcc/testsuite/g++.dg/expr/ptrmem9.C | 19 +++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 gcc/testsuite/g++.dg/expr/ptrmem8.C create mode 100644 gcc/testsuite/g++.dg/expr/ptrmem9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index caf0322972f..4f4691a0393 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 PR c++/79797 - ICE with self-reference in array DMI. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e4f03891228..18043e8c57f 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 5050929f1a8..cad76f21eed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-03-09 Marek Polacek + + PR c++/79687 + * g++.dg/expr/ptrmem8.C: New test. + * g++.dg/expr/ptrmem9.C: New test. + 2017-03-09 Richard Biener 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 00000000000..c5a766aa5b5 --- /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 00000000000..32ce777aeb8 --- /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); +} -- 2.30.2