On 7/2/26 1:29 AM, Vladislav Semykin wrote:
Good day! My mistake was that I continued talking in the same previous email thread, sorry about that.

No worries.

Changes since v2:
- Apply the same two-pass (unevaluated-then-evaluated) logic to template-dependent operands
    in tsubst_expr (TYPEID_EXPR), as Jason requested.
- Fix lambda capture: a polymorphic glvalue typeid operand inside a lambda without a capture-default    is now correctly diagnosed as "not captured". Root cause was typeid_evaluated_p rejecting    reference types and being gated on the "nonnull" flag, which is unrelated to the evaluated/unevaluated decision. - Factor the polymorphic-glvalue predicate out into a shared typeid_evaluated_p    helper used by the parser, tsubst, and build_typeid (Jason's request - avoids the checks
    drifting out of sync).
- Drop the cxx_dialect >= cxx11 gate: per Jason, DR613 applies in all modes,
    since finish_non_static_data_member doesn't check cxx_dialect either.
- Also fixes PR c++/68604 and PR c++/116385, and removes a now-stale xfail in
   g++.dg/coroutines/unevaluated.C (PR c++/68604).


Tested full CI on: x86_64 GNU/Linux 6.17.0-35-generic Ubuntu 24.04.
FYI, these tests are broken before my changes (the full test log via 'make -C gcc -k check-c++-all' attached too):

Yes, most of these are preexisting issues.

FAIL: c-c++-common/analyzer/flex-without-call-summaries.c  -std=c++11  at line 885 (test for warnings, line 884) XPASS: c-c++-common/analyzer/flex-without-call-summaries.c  -std=c++11 PR analyzer/103546 (test for bogus messages, line 892) FAIL: c-c++-common/analyzer/flex-without-call-summaries.c  -std=c++11 (test for excess errors) FAIL: g++.dg/guality/pr55665.C   -O2 -flto -fno-use-linker-plugin -flto- partition=none  line 23 p == 40 FAIL: g++.dg/modules/compile-std1.C -std=c++26 -fimplicit-constexpr (test for excess errors)

...but this one is surprising, can you look at testsuite/g++/g++.log to see what's breaking?

From acc669f9364264ecf93f1341e7037e916a798c6b Mon Sep 17 00:00:00 2001
From: Vladislav Semykin <[email protected]>
Date: Tue, 30 Jun 2026 19:13:14 +0300
Subject: [PATCH] c++: fix unevaluated operand context for typeid [PR125886]

Signed-off-by: Vladislav Semykin <[email protected]>

The commit message is missing both rationale and the ChangeLog entries that your v1 patch had, as git gcc-verify would point out.

+++ b/gcc/cp/cp-tree.h
@@ -6340,7 +6340,8 @@ extern bool cp_preserve_using_decl;
/* Nonzero if we are parsing an unevaluated operand: an operand to
    sizeof, typeof, or alignof.  This is a count since operands to
-   sizeof can be nested.  */
+   sizeof can be nested.  For typeid the operand is processed
+   unevaluated, then re-processed evaluated if polymorphic 
([expr.typeid]/4-5).  */
+++ b/gcc/cp/parser.cc
@@ -292,7 +292,9 @@ static void missing_template_diag
 static FILE *cp_lexer_debug_stream;
/* Nonzero if we are parsing an unevaluated operand: an operand to
-   sizeof, typeof, or alignof.  */
+   sizeof, typeof, or alignof.  This is a count since operands to
+   sizeof can be nested.  For typeid the operand is processed
+   unevaluated, then re-processed evaluated if polymorphic 
([expr.typeid]/4-5).  */

These matching comments are too long, as git gcc-style points out.

git gcc-style also flags the indentation problems in parser.cc and rtti.cc.

@@ -8570,9 +8572,30 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
        else
          {
            tree expression;
+           /* [expr.typeid]/4-5: parse the operand unevaluated first; if it is 
a
+              polymorphic glvalue, roll back and re-parse it evaluated, since 
an
+              evaluated parse has irreversible side-effects (mark_used ->
+              instantiation; lambda capture).  */
+           cp_lexer_save_tokens (parser->lexer);
+           ++cp_unevaluated_operand;
+           ++c_inhibit_evaluation_warnings;
+           expression = cp_parser_expression (parser, &idk);
+           --c_inhibit_evaluation_warnings;
+           --cp_unevaluated_operand;

Why not use cp_unevaluated here as in tsubst_expr?

+typeid_evaluated_p (tree exp)
+{
+  if (exp == error_mark_node)
+    return false;
+  tree t = TREE_TYPE (exp);
+  if (!t || t == error_mark_node)
+    return false;
+  if (TYPE_REF_P (t))
+    t = TREE_TYPE (t);
+  if (TREE_CODE (t) != RECORD_TYPE && TREE_CODE (t) != UNION_TYPE)
+    return false;
+  int nonnull = 0;
+  return (TYPE_POLYMORPHIC_P (t)
+         && !resolves_to_fixed_type_p (exp, &nonnull)
+         && glvalue_p (exp));

Do we need the added glvalue_p check? I would expect a prvalue to always resolve to a fixed type.

Jason

Reply via email to