>From Jason Merril:
> We should be able to just pass down the new nonnull parameter and drop
> the local variable.

>From Marek Polacek:
> The patch should also use nullptr instead of NULL and document the new
> parameter.

Done in v2.

Verified with gcc-verify and gcc-style.
Compiled tests with:

make check-c++ RUNTESTFLAGS="dg.exp=cpp0x/pr125886.C" && \
make check-c++ RUNTESTFLAGS="dg.exp=coroutines/unevaluated.C" && \
make check-c++ RUNTESTFLAGS="dg.exp=rtti/*.C" && \
make check-c++ RUNTESTFLAGS="dg.exp=cpp0x/constexpr-typeid*.C" && \
make check-c++ RUNTESTFLAGS="dg.exp=cpp2a/constexpr-typeid*.C" && \
make check-c++ RUNTESTFLAGS="dg.exp=template/typeid*.C"

All green.
From 36d2226058fa6015a1cec6b11afa7d5507147508 Mon Sep 17 00:00:00 2001
From: Vladislav Semykin <[email protected]>
Date: Mon, 13 Jul 2026 19:43:34 +0300
Subject: [PATCH v2] c++: avoid double resolves_to_fixed_type_p call [PR126207]
To: [email protected]

gcc/cp/ChangeLog:
	PR c++/126207
	* cp-tree.h (typeid_evaluated_p): Add nonnull out-parameter.
	* rtti.cc (typeid_evaluated_p): Likewise; avoid calling
	resolves_to_fixed_type_p twice.
	(build_typeid): Adjust.

Signed-off-by: Vladislav Semykin <[email protected]>
---
 gcc/cp/cp-tree.h |  2 +-
 gcc/cp/rtti.cc   | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8dac8c98b7a..35a8c48bac8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7486,7 +7486,7 @@ extern tree current_nonlambda_class_type	(void);
 extern tree finish_struct			(tree, tree);
 extern void finish_struct_1			(tree);
 extern int resolves_to_fixed_type_p		(tree, int * = NULL);
-extern bool typeid_evaluated_p (tree);
+extern bool typeid_evaluated_p (tree, int * = nullptr);
 extern void init_class_processing		(void);
 extern int is_empty_class			(tree);
 extern bool is_really_empty_class		(tree, bool);
diff --git a/gcc/cp/rtti.cc b/gcc/cp/rtti.cc
index 48e4dfde458..e92e8a7ddf6 100644
--- a/gcc/cp/rtti.cc
+++ b/gcc/cp/rtti.cc
@@ -342,10 +342,11 @@ typeid_ok_p (void)
 
 /* True if EXP is a glvalue expression of polymorphic class type whose
    dynamic type is not known statically, so that typeid (EXP) must be
-   evaluated per ([expr.typeid]/4).  */
+   evaluated per ([expr.typeid]/4).  If NONNULL is non-null, set
+   *NONNULL according to resolves_to_fixed_type_p.  */
 
 bool
-typeid_evaluated_p (tree exp)
+typeid_evaluated_p (tree exp, int *nonnull)
 {
   if (exp == error_mark_node)
     return false;
@@ -356,9 +357,9 @@ typeid_evaluated_p (tree exp)
     t = TREE_TYPE (t);
   if (TREE_CODE (t) != RECORD_TYPE && TREE_CODE (t) != UNION_TYPE)
     return false;
-  int nonnull = 0;
+  bool fixed = resolves_to_fixed_type_p (exp, nonnull);
   return (TYPE_POLYMORPHIC_P (t)
-	  && !resolves_to_fixed_type_p (exp, &nonnull)
+	  && !fixed
 	  /* Only a glvalue operand is evaluated ([expr.typeid]/4).
 	     The following check is only necessary because
 	     resolves_to_fixed_type_p does not handle all
@@ -380,10 +381,9 @@ build_typeid (tree exp, tsubst_flags_t complain)
   if (processing_template_decl)
     return build_min (TYPEID_EXPR, const_type_info_type_node, exp);
 
-  if (typeid_evaluated_p (exp))
+  int nonnull = 0;
+  if (typeid_evaluated_p (exp, &nonnull))
     {
-      int nonnull = 0;
-      resolves_to_fixed_type_p (exp, &nonnull);
       if (!nonnull)
 	{
 	  /* Make sure it isn't a null lvalue; evaluate it once.  */

base-commit: 6df03d626ffe309c4ca1e36fb08441325dc1c46e
-- 
2.43.0

Reply via email to