From: Jason Merrill Date: Tue, 22 Dec 2020 21:40:37 +0000 (-0500) Subject: c++: Fix constexpr array ICE [PR98332] X-Git-Tag: releases/gcc-10.3.0~495 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f5cea9c5c4f8cce36963973e432a8575ef9ffd63;p=thirdparty%2Fgcc.git c++: Fix constexpr array ICE [PR98332] The element initializer was non-constant, so its CONSTRUCTOR element ended up NULL, so unshare_constructor crashed trying to look at it. This patch fixes this in two places: First, by returning when we see a non-constant initializer; second, by not crashing on NULL. gcc/cp/ChangeLog: PR c++/98332 * constexpr.c (unshare_constructor): Check for NULL. (cxx_eval_vec_init_1): Always exit early if non-constant. gcc/testsuite/ChangeLog: PR c++/98332 * g++.dg/cpp0x/constexpr-overflow3.C: New test. --- diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index ff6518d2de68..1f22a8b9ef8a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1464,7 +1464,7 @@ unshare_constructor (tree t MEM_STAT_DECL) vec *v = CONSTRUCTOR_ELTS (n); constructor_elt *ce; for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i) - if (TREE_CODE (ce->value) == CONSTRUCTOR) + if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR) ptrs.safe_push (&ce->value); } return t; @@ -4139,7 +4139,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval, non_constant_p, overflow_p); } - if (*non_constant_p && !ctx->quiet) + if (*non_constant_p) break; if (new_ctx.ctor != ctx->ctor) { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-overflow3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-overflow3.C new file mode 100644 index 000000000000..61766257e39f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-overflow3.C @@ -0,0 +1,7 @@ +// PR c++/98332 +// { dg-do compile { target c++11 } } + +#include + +struct S { int a = INT_MAX + 1; }; // { dg-warning "overflow" } +struct { S b[2][1][1][1]; } c;