On Wed, Mar 15, 2023 at 12:48:27PM -0400, Jason Merrill wrote: > On 3/15/23 10:37, Marek Polacek wrote: > > On Fri, Mar 10, 2023 at 01:47:46PM -0500, Jason Merrill wrote: > > > On 3/10/23 11:17, Marek Polacek wrote: > > > > We crash here since r10-3661, the store_init_value hunk in particular. > > > > Before, we called cp_fully_fold_init, so e.g. > > > > > > > > {.str=VIEW_CONVERT_EXPR<char[8]>("")} > > > > > > > > was folded into > > > > > > > > {.str=""} > > > > > > > > but now we don't fold and keep the VCE around, and it causes trouble in > > > > cxx_eval_store_expression: in the !refs->is_empty () loop we descend on > > > > .str's initializer but since it's wrapped in a VCE, we skip the > > > > STRING_CST > > > > check and then crash on the CONSTRUCTOR_NO_CLEARING. > > > > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/12? > > > > > > > > PR c++/107280 > > > > > > > > gcc/cp/ChangeLog: > > > > > > > > * constexpr.cc (cxx_eval_store_expression): Strip location > > > > wrappers. > > > > > > > > gcc/testsuite/ChangeLog: > > > > > > > > * g++.dg/cpp1z/constexpr-lambda28.C: New test. > > > > --- > > > > gcc/cp/constexpr.cc | 3 ++- > > > > gcc/testsuite/g++.dg/cpp1z/constexpr-lambda28.C | 15 +++++++++++++++ > > > > 2 files changed, 17 insertions(+), 1 deletion(-) > > > > create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-lambda28.C > > > > > > > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > > > > index 8683c00596a..abf6ee560c5 100644 > > > > --- a/gcc/cp/constexpr.cc > > > > +++ b/gcc/cp/constexpr.cc > > > > @@ -6033,7 +6033,8 @@ cxx_eval_store_expression (const constexpr_ctx > > > > *ctx, tree t, > > > > *valp = build_constructor (type, NULL); > > > > CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init; > > > > } > > > > - else if (TREE_CODE (*valp) == STRING_CST) > > > > + else if (STRIP_ANY_LOCATION_WRAPPER (*valp), > > > > + TREE_CODE (*valp) == STRING_CST) > > > > > > Seems like this is stripping the location wrapper when we try to modify > > > the > > > string; I think we want to strip it earlier, when we first initialize the > > > array member. > > > > Hmm, I suppose we don't want to do the stripping too early. I could > > have put it in get_nsdmi, for instance, but maybe here is good as well? > > I guess I was thinking more around the time when the value is imported into > constant evaluation, i.e. this chunk of cxx_eval_constant_expression: > > > if (tree init = DECL_INITIAL (r)) > > { > > init = cxx_eval_constant_expression (ctx, init, vc_prvalue, > > non_constant_p, > > overflow_p); > > /* Don't share a CONSTRUCTOR that might be changed. */ > > init = unshare_constructor (init); > > /* Remember that a constant object's constructor has already > > run. */ > > if (CLASS_TYPE_P (TREE_TYPE (r)) > > && CP_TYPE_CONST_P (TREE_TYPE (r))) > > TREE_READONLY (init) = true; > > ctx->global->put_value (r, init); > > }
Ah, that wouldn't fix the problem as far as I can tell -- here init is the whole constructor: {.str=VIEW_CONVERT_EXPR<char[8]>("")} so we'd not have a way to strip the inner init. > Feel free to pursue that approach or go ahead and push your first patch, > whichever you prefer. The original patch it is, then. Thanks. Marek