Hi! cxx_eval_outermost_constant_expr clears TREE_CONSTANT on ADDR_EXPRs that aren't considered by C++ constant expressions, but that breaks middle-end which relies on TREE_CONSTANT being set on ADDR_EXPR where the address is constant.
The following patch just special cases ADDR_EXPR not to clear it. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? As I wrote in the PR, another option would be to restore TREE_CONSTANT during genericization if it was cleared earlier in the FE. 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)) --- gcc/testsuite/g++.dg/init/pr83993-2.C.jj 2018-01-24 17:04:18.823456178 +0100 +++ gcc/testsuite/g++.dg/init/pr83993-2.C 2018-01-24 17:04:39.593454636 +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