https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P1 |P2 CC| |jason at gcc dot gnu.org Target Milestone|--- |8.0 Summary|[8 Regression] ICE: |[7/8 Regression] ICE: |constant not recomputed |constant not recomputed |when ADDR_EXPR changed |when ADDR_EXPR changed --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Because the array has no TYPE_DOMAIN, in cxx_eval_array_reference if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE) nelts = array_type_nelts_top (TREE_TYPE (ary)); sets nelts to error_mark_node + 1, and so the cxx_eval_constant_expression calls sets *non_constant_p. Then later on the caller of this, cxx_eval_outermost_constant_expr, does: 4818 else if (non_constant_p && TREE_CONSTANT (r)) 4819 { 4820 /* This isn't actually constant, so unset TREE_CONSTANT. */ 4821 if (EXPR_P (r)) 4822 r = copy_node (r); 4823 else if (TREE_CODE (r) == CONSTRUCTOR) 4824 r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r); 4825 else 4826 r = build_nop (TREE_TYPE (r), r); 4827 TREE_CONSTANT (r) = false; 4828 } on the ADDR_EXPR surrounding the ARRAY_REF. So, the questions are: 1) if we have such [] arrays, does any access to any element in the array imply a non-constant expression, or should we ignore the in-bounds check? E.g. on extern const int a[]; const int b[5] = { 1, 2, 3, 4, 5 }; extern const int c[5]; constexpr const int *d = &a[0]; constexpr const int *e = &a[10]; constexpr const int *f = &b[0]; constexpr const int *g = &b[5]; constexpr const int *h = &b[6]; constexpr const int *i = &b[0]; constexpr const int *j = &b[5]; constexpr const int *k = &b[6]; g++ errors on h and k definitions, while clang++ errors on e, h, k, somehow it considers &a[0] to be always ok no matter how large the array is (that is actually a reasonable assumption for lval case, even if the array has zero size, it is still valid to form a pointer past it), but considers &a[10] invalid, even when the other TU could have const int a[100]. 2) does cxx_eval_outermost_constant_expr really need to clear TREE_CONSTANT even on ADDR_EXPRs, or could we special case those? If we need to clear those, supposedly during genericization we should try to recompute the ADDR_EXPR flags and if that would change them, copy node and restore there what the middle-end expects. Jason, do you have answers to these questions, please?