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
@@ -753,7 +753,7 @@ fn F() {
}
// ============================================================================
// Incomplete operand
// Incomplete operand C++ type
// ============================================================================
// --- incomplete.h
@@ -784,6 +784,72 @@ fn F() {
let c3: Cpp.Complete = Cpp.foo(c1 + ({} as Cpp.Incomplete));
}
// ============================================================================
// Incomplete operand Carbon type
// ============================================================================
// --- complete.h
struct Complete {};
// --- fail_incomplete_operand_carbon_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "complete.h";
class Incomplete;
fn CreateIncomplete() -> Incomplete*;
fn F() {
var complete: Cpp.Complete = Cpp.Complete.Complete();
// CHECK:STDERR: fail_incomplete_operand_carbon_type.carbon:[[@LINE+10]]:21: error: looking up a C++ operator with incomplete operand type `Incomplete` [IncompleteOperandTypeInCppOperatorLookup]
// CHECK:STDERR: let result: i32 = *CreateIncomplete() + complete;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_incomplete_operand_carbon_type.carbon:[[@LINE-8]]:1: note: class was forward declared here [ClassForwardDeclaredHere]
// CHECK:STDERR: class Incomplete;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_incomplete_operand_carbon_type.carbon:[[@LINE+4]]:21: note: in `Cpp` operator `AddWith` lookup [InCppOperatorLookup]
// CHECK:STDERR: let result: i32 = *CreateIncomplete() + complete;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
let result: i32 = *CreateIncomplete() + complete;
}
// ============================================================================
// Unsupported operand type in instantiation
// ============================================================================
// --- unsupported_in_instantiation.h
struct Supported {};
template<typename T>
struct Unsupported : public virtual Supported {};
using UnsupportedAlias = Unsupported<int>;
extern UnsupportedAlias unsupported;
// --- fail_import_unsupported_in_instantiation.carbon
library "[[@TEST_NAME]]";
import Cpp library "unsupported_in_instantiation.h";
fn F() {
var supported: Cpp.Supported = Cpp.Supported.Supported();
// CHECK:STDERR: fail_import_unsupported_in_instantiation.carbon:[[@LINE+10]]:21: error: semantics TODO: `class with virtual bases` [SemanticsTodo]
// CHECK:STDERR: let result: i32 = supported + Cpp.unsupported;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_import_unsupported_in_instantiation.carbon:[[@LINE+7]]:21: note: while completing C++ type `Cpp.Unsupported` [InCppTypeCompletion]
// CHECK:STDERR: let result: i32 = supported + Cpp.unsupported;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_import_unsupported_in_instantiation.carbon:[[@LINE+4]]:21: note: in `Cpp` operator `AddWith` lookup [InCppOperatorLookup]
// CHECK:STDERR: let result: i32 = supported + Cpp.unsupported;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
let result: i32 = supported + Cpp.unsupported;
}
// ============================================================================
// Operator overloading
// ============================================================================