When looking up C++ operators, make sure all operands are complete (#6132)

This diagnoses instead of crashing in some cases:
* When one of the operands is an incomplete Carbon type.
* When one of the operands is a C++ class that can't be completed due to
lack of Carbon supported.
The new tests cover these cases.

Part of #5995.
This commit is contained in:
Boaz Brickner
2025-09-25 14:15:02 +00:00
committed by GitHub
parent fd70196c67
commit 3bb0d3e0b1
4 changed files with 98 additions and 9 deletions
+18 -3
View File
@@ -10,6 +10,7 @@
#include "toolchain/check/cpp/type_mapping.h"
#include "toolchain/check/inst.h"
#include "toolchain/check/type.h"
#include "toolchain/check/type_completion.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::Check {
@@ -169,19 +170,33 @@ auto LookupCppOperator(Context& context, SemIR::LocId loc_id, Operator op,
return SemIR::InstId::None;
}
// Make sure all operands are complete before lookup.
for (SemIR::InstId arg_id : arg_ids) {
SemIR::TypeId arg_type_id = context.insts().Get(arg_id).type_id();
if (!RequireCompleteType(context, arg_type_id, loc_id, [&] {
CARBON_DIAGNOSTIC(
IncompleteOperandTypeInCppOperatorLookup, Error,
"looking up a C++ operator with incomplete operand type {0}",
SemIR::TypeId);
return context.emitter().Build(
loc_id, IncompleteOperandTypeInCppOperatorLookup, arg_type_id);
})) {
return SemIR::ErrorInst::InstId;
}
}
auto arg_exprs = InventClangArgs(context, arg_ids);
if (!arg_exprs.has_value()) {
return SemIR::ErrorInst::InstId;
}
clang::Sema& sema = context.clang_sema();
clang::UnresolvedSet<4> functions;
// TODO: Add location accordingly.
clang::OverloadCandidateSet candidate_set(
clang::SourceLocation(), clang::OverloadCandidateSet::CSK_Operator);
// This works for both unary and binary operators.
sema.LookupOverloadedBinOp(candidate_set, *op_kind, functions, *arg_exprs);
context.clang_sema().LookupOverloadedBinOp(candidate_set, *op_kind, functions,
*arg_exprs);
for (auto& it : candidate_set) {
if (!it.Function) {