diff options
author | Jason Merrill <jason@redhat.com> | 2018-01-31 21:46:36 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-01-31 21:46:36 +0100 |
commit | eddd715c77c55f342e41419410fc577f71905800 (patch) | |
tree | 88ce6921e6b3e02d3f87cd5d853b4f38d0780406 | |
parent | 08b3748ce73c94460f314cb34f21702049650e72 (diff) | |
download | gcc-eddd715c77c55f342e41419410fc577f71905800.zip gcc-eddd715c77c55f342e41419410fc577f71905800.tar.gz gcc-eddd715c77c55f342e41419410fc577f71905800.tar.bz2 |
re PR c++/83993 (ICE: constant not recomputed when ADDR_EXPR changed)
PR c++/83993
* constexpr.c (cxx_eval_outermost_constant_expr): Build NOP_EXPR
around non-constant ADDR_EXPRs rather than clearing TREE_CONSTANT
on ADDR_EXPR.
* g++.dg/init/pr83993-2.C: New test.
From-SVN: r257265
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/pr83993-2.C | 14 |
4 files changed, 31 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c8df8f1..6eb7f27 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-01-31 Jason Merrill <jason@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + PR c++/83993 + * constexpr.c (cxx_eval_outermost_constant_expr): Build NOP_EXPR + around non-constant ADDR_EXPRs rather than clearing TREE_CONSTANT + on ADDR_EXPR. + 2018-01-31 Jakub Jelinek <jakub@redhat.com> PR c++/83993 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 087d8d8..1390405 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4840,8 +4840,12 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, return error_mark_node; else if (non_constant_p && TREE_CONSTANT (r)) { - /* This isn't actually constant, so unset TREE_CONSTANT. */ - if (EXPR_P (r)) + /* This isn't actually constant, so unset TREE_CONSTANT. + Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires + it to be set if it is invariant address, even when it is not + a valid C++ constant expression. Wrap it with a NOP_EXPR + instead. */ + if (EXPR_P (r) && TREE_CODE (r) != ADDR_EXPR) r = copy_node (r); else if (TREE_CODE (r) == CONSTRUCTOR) r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5feda0b..3f110a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,9 @@ 2018-01-31 Jakub Jelinek <jakub@redhat.com> PR c++/83993 + * g++.dg/init/pr83993-2.C: New test. + + PR c++/83993 * g++.dg/init/pr83993-1.C: New test. * g++.dg/cpp0x/pr83993.C: New test. diff --git a/gcc/testsuite/g++.dg/init/pr83993-2.C b/gcc/testsuite/g++.dg/init/pr83993-2.C new file mode 100644 index 0000000..19f5408 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr83993-2.C @@ -0,0 +1,14 @@ +// PR c++/83993 +// { dg-do compile } +// { dg-options "-w" } + +int a[5]; +extern int b[]; +int *const c = &a[6]; +int *const d = &b[1]; + +int +foo () +{ + return c[-4] + d[-1]; +} |