Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< --
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. --- 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 f30cf3fcd09..6cd6e8f1bfc 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 80fd7990bbb..b1626acb50b 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; base-commit: f359b9150c282c69704d8d2a6c8e071c90506538 -- 2.49.0