diff mbox

Fix PR68087

Message ID 20151026113222.GA418@x4
State New
Headers show

Commit Message

Markus Trippelsdorf Oct. 26, 2015, 11:32 a.m. UTC
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().

Comments

Richard Biener Oct. 26, 2015, 12:26 p.m. UTC | #1
On Mon, Oct 26, 2015 at 12:32 PM, Markus Trippelsdorf
<markus@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
diff mbox

Patch

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)
     {
       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" }