From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7810) id BDFAC3846472; Mon, 13 Jun 2022 10:13:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BDFAC3846472 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alex Coplan To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] cp: Fix ICEs evaluating dynamic_cast in constexpr context X-Act-Checkin: gcc X-Git-Author: Alex Coplan X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: fc9ffafb915e23b718ade4f952db1f2939732c86 X-Git-Newrev: a54686a53cfd2ea7017d3b583877be5c2b91d19d Message-Id: <20220613101335.BDFAC3846472@sourceware.org> Date: Mon, 13 Jun 2022 10:13:35 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Jun 2022 10:13:35 -0000 https://gcc.gnu.org/g:a54686a53cfd2ea7017d3b583877be5c2b91d19d commit a54686a53cfd2ea7017d3b583877be5c2b91d19d Author: Alex Coplan Date: Tue Mar 22 11:42:07 2022 +0000 cp: Fix ICEs evaluating dynamic_cast in constexpr context cxx_eval_dynamic_cast_fn was returning integer_zero_node in failure cases, but __dynamic_cast is required to return a pointer type. The calling code was trying to NOP_EXPR the resulting integer to a pointer, which is invalid with capabilities. Fixed by changing cxx_eval_dynamic_cast_fn to return null_pointer_node in failure cases. We also need to adjust the CONVERT_EXPR case of cxx_eval_constant_expression: with the above change, we now trip a diagnostic here that complains we're doing an invalid conversion between null pointer types. We suppress this diagnostic in the case where the operand being converted was originally a dynamic_cast, since the diagnostic we actually want in this case is the one that will later be produced by cxx_eval_dynamic_cast_fn. Diff: --- gcc/cp/constexpr.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 5294dc452e9..5fa5d433c5d 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1973,7 +1973,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, } *non_constant_p = true; } - return integer_zero_node; + return null_pointer_node; } /* [class.cdtor] When a dynamic_cast is used in a constructor ... @@ -2020,7 +2020,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, } *non_constant_p = true; } - return integer_zero_node; + return null_pointer_node; } else if (t) /* The result points to the TYPE object. */ @@ -2050,7 +2050,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, } *non_constant_p = true; } - return integer_zero_node; + return null_pointer_node; } else gcc_assert (obj); @@ -2076,7 +2076,7 @@ cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call, } *non_constant_p = true; } - return integer_zero_node; + return null_pointer_node; } /* If so, return the TYPE subobject of the most derived object. */ obj = convert_to_base_statically (obj, binfo); @@ -2175,6 +2175,19 @@ cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl, non_constant_p, overflow_p); } +static bool +cxx_dynamic_cast_call_p (tree t) +{ + if (TREE_CODE (t) != CALL_EXPR) + return false; + + tree fn = get_function_named_in_call (t); + if (!fn) + return false; + + return cxx_dynamic_cast_fn_p (fn); +} + /* Subroutine of cxx_eval_constant_expression. Evaluate the call expression tree T in the context of OLD_CALL expression evaluation. */ @@ -6318,7 +6331,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, { tree from = TREE_TYPE (op); - if (!can_convert (type, from, tf_none)) + /* Don't diagnose the conversion of a null pointer from + evaluating calls to dynamic_cast: null pointer means the + dynamic_cast failed; this will be diagnosed later. */ + if (!cxx_dynamic_cast_call_p (oldop) + && !can_convert (type, from, tf_none)) { if (!ctx->quiet) error_at (loc,