On Mon, Oct 26, 2015 at 12:32 PM, Markus Trippelsdorf <mar...@trippelsdorf.de> wrote: > Hi, > > the patch below fixes PR68087, an ICE caused by referring to a negative > constexpr array element. > > Bootstrapped and tested on ppc64le. > OK for trunk? > > gcc-5 also needs a slightly different fix. I'll post that as a > follow-up, once this one gets approved. > > PR c++/68087 > * constexpr.c (cxx_eval_array_reference): Guard call to > tree_to_shwi(). > > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c > index ebca411b3eb4..0828a90b0e75 100644 > --- a/gcc/cp/constexpr.c > +++ b/gcc/cp/constexpr.c > @@ -1782,8 +1782,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, > tree t, > gcc_unreachable (); > } > > - i = tree_to_shwi (index); > - if (i < 0) > + if (!tree_fits_shwi_p (index) || tree_to_shwi (index) < 0) > {
Err, but that also catches very large positive constants. Why not use wi::lt (index, 0)? Or is index to be interpreted as signed? Then use wi::lts (index, 0). > if (!ctx->quiet) > error ("negative array subscript"); > @@ -1792,6 +1791,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, > tree t, > } > > bool found; > + i = tree_to_shwi (index); > if (TREE_CODE (ary) == CONSTRUCTOR) > { > HOST_WIDE_INT ix = find_array_ctor_elt (ary, index); > diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C > b/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C > new file mode 100644 > index 000000000000..ef18a60f3038 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array13.C > @@ -0,0 +1,7 @@ > +// PR c++/68087 > +// { dg-do compile { target c++11 } } > + > +constexpr char c[] = "hello"; > +constexpr const char *p = c; > + > +static_assert(*(p - 1) == 'h', ""); // { dg-error "non-constant|negative" } > -- > Markus