[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Jan 23 16:06:00 GMT 2018
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?
More information about the Gcc-bugs
mailing list