https://gcc.gnu.org/g:1f4a917c610f7c199a6de1eab4fcdc878e4fc5ac
commit r16-1748-g1f4a917c610f7c199a6de1eab4fcdc878e4fc5ac Author: Jason Merrill <ja...@redhat.com> Date: Wed Jun 25 16:26:56 2025 -0400 c++: fix decltype_p handling for binary expressions With Jakub's constexpr virtual base patch, 23_containers/vector/bool/cmp_c++20.cc failed the assert I add to fixed_type_or_null, meaning that it returned the wrong value. Let's fix the result as well as adding the assert, and fix cp_parser_binary_expression to properly wrap any class-type calls in the operands in TARGET_EXPR even within a decltype so we don't hit the assert. gcc/cp/ChangeLog: * class.cc (fixed_type_or_null): Handle class-type CALL_EXPR. * parser.cc (cp_parser_binary_expression): Fix decltype_p handling. Diff: --- gcc/cp/class.cc | 9 +++++++++ gcc/cp/parser.cc | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index f30cf3fcd095..6cd6e8f1bfcf 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -8350,6 +8350,15 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp) *nonnull = 1; return TREE_TYPE (instance); } + if (CLASS_TYPE_P (TREE_TYPE (instance))) + { + /* We missed a build_cplus_new somewhere, likely due to tf_decltype + mishandling. */ + gcc_checking_assert (false); + if (nonnull) + *nonnull = 1; + return TREE_TYPE (instance); + } return NULL_TREE; case SAVE_EXPR: diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 80fd7990bbbb..b1626acb50b7 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -10835,6 +10835,14 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p, goto pop; } + /* If we skipped build_cplus_new in build_cxx_call because of decltype_p, + call it now that we know current.lhs is a subexpression. */ + if (decltype_p && !processing_template_decl + && TREE_CODE (current.lhs) == CALL_EXPR + && CLASS_TYPE_P (TREE_TYPE (current.lhs))) + current.lhs = build_cplus_new (TREE_TYPE (current.lhs), current.lhs, + tf_warning_or_error); + get_rhs: current.tree_type = binops_by_token[token->type].tree_type; current.loc = token->location;