diff options
author | Marek Polacek <polacek@redhat.com> | 2017-03-09 16:36:37 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2017-03-09 16:36:37 +0000 |
commit | 6443c7c0e5e1b348ff5841463e3c3828b3036e30 (patch) | |
tree | 22baa88c105d2a2309c26e858445dfc6186a00fd /gcc | |
parent | d721dc3c4bb4a29f6c2cee5be88710a1b107e2f2 (diff) | |
download | gcc-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/ptrmem8.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/expr/ptrmem9.C | 19 |
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); +} |