[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 --- Comment #8 from Jakub Jelinek --- Author: jakub Date: Wed Jan 31 20:46:36 2018 New Revision: 257265 URL: https://gcc.gnu.org/viewcvs?rev=257265=gcc=rev Log: 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. Added: trunk/gcc/testsuite/g++.dg/init/pr83993-2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/testsuite/ChangeLog
[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 --- Comment #7 from Jakub Jelinek --- Author: jakub Date: Wed Jan 31 20:45:41 2018 New Revision: 257264 URL: https://gcc.gnu.org/viewcvs?rev=257264=gcc=rev Log: PR c++/83993 * constexpr.c (diag_array_subscript): Emit different diagnostics if TYPE_DOMAIN (arraytype) is NULL. (cxx_eval_array_reference, cxx_eval_store_expression): For arrays with NULL TYPE_DOMAIN use size_zero_node as nelts. * g++.dg/init/pr83993-1.C: New test. * g++.dg/cpp0x/pr83993.C: New test. Added: trunk/gcc/testsuite/g++.dg/cpp0x/pr83993.C trunk/gcc/testsuite/g++.dg/init/pr83993-1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/testsuite/ChangeLog
[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 Richard Biener changed: What|Removed |Added Target Milestone|7.3 |7.4 --- Comment #6 from Richard Biener --- GCC 7.3 is being released, adjusting target milestone.
[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 Jakub Jelinek changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org --- Comment #5 from Jakub Jelinek --- Created attachment 43232 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43232=edit gcc8-pr83993.patch Untested patch for the 1) part. With this the testcase doesn't ICE anymore, but modified testcase like: extern const int a[]; const int *const b = [1]; int foo () { return b[0]; } still ICEs, so 2) needs to be resolved too.
[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 Richard Biener changed: What|Removed |Added Target Milestone|8.0 |7.3
[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 --- Comment #4 from Jakub Jelinek --- The clang++ error on e is: pr83993-2.C:5:22: error: constexpr variable 'e' must be initialized by a constant expression constexpr const int *e = [10]; ^ ~~ pr83993-2.C:5:27: note: indexing of array without known bound is not allowed in a constant expression constexpr const int *e = [10]; ^ Note, diag_array_subscript is called in constexpr.c multiple times, if we go for allowing lval ary[0] for array of unknown bounds, but disallow ary[N] for N != 0 for lval or any N for !lval, we'd need 2 other diagnostic messages in diag_array_subscript and handle these cases in the callers. Another case that needs testing is const int array[0]; and [] arrays with initializers from which the size is determined.
[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83993 Jakub Jelinek 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 --- 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)) 4822r = copy_node (r); 4823 else if (TREE_CODE (r) == CONSTRUCTOR) 4824r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r); 4825 else 4826r = 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 = [0]; constexpr const int *e = [10]; constexpr const int *f = [0]; constexpr const int *g = [5]; constexpr const int *h = [6]; constexpr const int *i = [0]; constexpr const int *j = [5]; constexpr const int *k = [6]; g++ errors on h and k definitions, while clang++ errors on e, h, k, somehow it considers [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 [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?