From 9b1d5ef0c5ad93636bbf1dc22c6007b7d935e44c Mon Sep 17 00:00:00 2001 From: Vladislav Semykin <[email protected]> Date: Wed, 24 Jun 2026 22:47:58 +0300 Subject: [PATCH] cp: fix unevaluated operand context for typeid
PR c++/125886 - std::declval in unevaluated typeid operand incorrectly triggers __declval_protector PR c++/125886 PR 125886 gcc/cp/ChangeLog: * cp-tree.h (cp_unevaluated_operand): Mention typeid in comment. * parser.cc (cp_parser_postfix_expression): Set cp_unevaluated_operand and c_inhibit_evaluation_warnings before parsing typeid expression operand. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/pr125886.C: New test. Signed-off-by: Vladislav Semykin <[email protected]> --- gcc/cp/cp-tree.h | 5 +++-- gcc/cp/parser.cc | 5 +++++ gcc/testsuite/g++.dg/cpp0x/pr125886.C | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr125886.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 132139f9d..25021c62d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6339,8 +6339,9 @@ extern bool comparing_contracts; 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, typeof, alignof, or typeid (when the operand is not + of polymorphic class type). This is a count since operands + to sizeof can be nested. */ extern int cp_unevaluated_operand; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 8194106c6..d426ff655 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -8571,8 +8571,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, { tree expression; + /* As for sizeof and noexcept before parsing. */ + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; /* Look for an expression. */ expression = cp_parser_expression (parser, & idk); + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; /* Compute its typeid. */ postfix_expression = build_typeid (expression, tf_warning_or_error); /* Look for the `)' token. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/pr125886.C b/gcc/testsuite/g++.dg/cpp0x/pr125886.C new file mode 100644 index 000000000..70db1e89e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr125886.C @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c++11" } */ + +#include <typeinfo> +#include <utility> + +class A {}; +void foo() { char const *a = typeid(std::declval<A>()).name(); } -- 2.43.0
