On Wed, Jan 31, 2018 at 11:05:17AM -0500, Jason Merrill wrote: > > 2018-01-24 Jakub Jelinek <ja...@redhat.com> > > > > PR c++/83993 > > * constexpr.c (cxx_eval_outermost_constant_expr): Don't clear > > TREE_CONSTANT on ADDR_EXPRs. > > > > * g++.dg/init/pr83993-2.C: New test. > > > > --- gcc/cp/constexpr.c.jj 2018-01-24 13:38:40.572913190 +0100 > > +++ gcc/cp/constexpr.c 2018-01-24 17:03:16.821440047 +0100 > > @@ -4832,7 +4832,7 @@ cxx_eval_outermost_constant_expr (tree t > > > > if (non_constant_p && !allow_non_constant) > > return error_mark_node; > > - else if (non_constant_p && TREE_CONSTANT (r)) > > + else if (non_constant_p && TREE_CONSTANT (r) && TREE_CODE (r) != > > ADDR_EXPR) > > { > > /* This isn't actually constant, so unset TREE_CONSTANT. */ > > if (EXPR_P (r)) > > Hmm, what if we check for ADDR_EXPR in the EXPR_P test, so we build a > non-TREE_CONSTANT NOP_EXPR around the ADDR_EXPR instead?
That looks like a good idea and works on the testcase in question, ok for trunk if it passes bootstrap/regtest? 2018-01-31 Jason Merrill <ja...@redhat.com> Jakub Jelinek <ja...@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. * g++.dg/init/pr83993-2.C: New test. --- gcc/cp/constexpr.c.jj 2018-01-30 12:30:24.279362188 +0100 +++ gcc/cp/constexpr.c 2018-01-31 17:18:03.316302653 +0100 @@ -4824,7 +4824,7 @@ cxx_eval_outermost_constant_expr (tree t else if (non_constant_p && TREE_CONSTANT (r)) { /* This isn't actually constant, so unset TREE_CONSTANT. */ - if (EXPR_P (r)) + 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); --- gcc/testsuite/g++.dg/init/pr83993-2.C.jj 2018-01-31 17:17:04.755290928 +0100 +++ gcc/testsuite/g++.dg/init/pr83993-2.C 2018-01-31 17:17:04.755290928 +0100 @@ -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]; +} Jakub