From 0df73beea03f9dc124dc6e98ec4bdeacca7a2eea Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 15 Oct 2020 16:10:45 -0400 Subject: c++: Fix verify_ctor_sanity ICE [PR96241] The code added in r10-6437 caused us to create a CONSTRUCTOR when we're {}-initializing an aggregate. Then we pass this new CONSTRUCTOR down to cxx_eval_constant_expression which, if the CONSTRUCTOR isn't TREE_CONSTANT or reduced_constant_expression_p, calls cxx_eval_bare_aggregate. In this case the CONSTRUCTOR wasn't reduced_constant_expression_p because for r_c_e_p a CONST_DECL isn't good enough so it returns false. So we go to cxx_eval_bare_aggregate where we crash, because ctx->ctor wasn't set up properly. So my fix is to do so. Since we're value-initializing, I'm not setting CONSTRUCTOR_NO_CLEARING. To avoid keeping a garbage constructor around, I call free_constructor in case the evaluation did not use it. gcc/cp/ChangeLog: PR c++/96241 * constexpr.c (cxx_eval_array_reference): Set up ctx->ctor if we are initializing an aggregate. Call free_constructor on the new CONSTRUCTOR if it isn't returned from cxx_eval_constant_expression. gcc/testsuite/ChangeLog: PR c++/96241 * g++.dg/cpp0x/constexpr-96241.C: New test. * g++.dg/cpp1y/constexpr-96241.C: New test. --- gcc/cp/constexpr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'gcc/cp') diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 4707d29..7ebdd30 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3657,15 +3657,22 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, initializer, it's initialized from {}. But use build_value_init directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */ tree val; + constexpr_ctx new_ctx; if (CP_AGGREGATE_TYPE_P (elem_type)) { tree empty_ctor = build_constructor (init_list_type_node, NULL); val = digest_init (elem_type, empty_ctor, tf_warning_or_error); + new_ctx = *ctx; + new_ctx.ctor = build_constructor (elem_type, NULL); + ctx = &new_ctx; } else val = build_value_init (elem_type, tf_warning_or_error); - return cxx_eval_constant_expression (ctx, val, lval, non_constant_p, - overflow_p); + t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p, + overflow_p); + if (CP_AGGREGATE_TYPE_P (elem_type) && t != ctx->ctor) + free_constructor (ctx->ctor); + return t; } /* Subroutine of cxx_eval_constant_expression. -- cgit v1.1