[Bug c++/83993] [7/8 Regression] ICE: constant not recomputed when ADDR_EXPR changed

2018-01-31 Thread jakub at gcc dot gnu.org
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

2018-01-31 Thread jakub at gcc dot gnu.org
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

2018-01-25 Thread rguenth at gcc dot gnu.org
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

2018-01-24 Thread jakub at gcc dot gnu.org
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

2018-01-24 Thread rguenth at gcc dot gnu.org
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

2018-01-23 Thread jakub at gcc dot gnu.org
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

2018-01-23 Thread jakub at gcc dot gnu.org
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?