Avoid crashing when importing a C++ struct indirectly (#6086)

Return an error constant id instead and output a TODO.

Part of #6060.
This commit is contained in:
Boaz Brickner
2025-09-17 17:27:52 +00:00
committed by GitHub
parent 02ea39f2a4
commit cac3578b86
2 changed files with 62 additions and 0 deletions
+8
View File
@@ -447,6 +447,9 @@ class ImportRefResolver : public ImportContext {
// Step 1: check for a constant value.
auto existing = FindResolvedConstId(work.inst_id);
if (existing.const_id == SemIR::ErrorInst::ConstantId) {
return existing.const_id;
}
if (existing.const_id.has_value() && !work.retry_with_constant_value) {
work_stack_.pop_back();
continue;
@@ -583,6 +586,11 @@ class ImportRefResolver : public ImportContext {
return result;
}
auto ir_inst = cursor_ir->import_ir_insts().Get(import_ir_inst_id);
if (ir_inst.ir_id() == SemIR::ImportIRId::Cpp) {
local_context().TODO(SemIR::LocId::None,
"Unsupported: Importing C++ indirectly");
return {.const_id = SemIR::ErrorInst::ConstantId};
}
const auto* prev_ir = cursor_ir;
auto prev_inst_id = cursor_inst_id;
+54
View File
@@ -46,6 +46,37 @@ fn F() {
//@dump-sem-ir-end
}
// ============================================================================
// Import C++ struct indirectly
// ============================================================================
// --- struct.h
struct MyStruct { void Foo(); };
// --- struct_api.carbon
library "[[@TEST_NAME]]";
import Cpp library "struct.h";
alias MyStructAlias = Cpp.MyStruct;
// --- fail_todo_import_struct_api.carbon
// CHECK:STDERR: fail_todo_import_struct_api.carbon: error: semantics TODO: `Unsupported: Importing C++ indirectly` [SemanticsTodo]
// CHECK:STDERR:
library "[[@TEST_NAME]]";
import library "struct_api";
fn F() {
//@dump-sem-ir-begin
var x: MyStructAlias;
x.Foo();
//@dump-sem-ir-end
}
// ============================================================================
// Import C++ function indirectly
// ============================================================================
@@ -101,6 +132,29 @@ fn F() {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_import_struct_api.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Main.MyStructAlias: type = import_ref Main//struct_api, MyStructAlias, loaded [concrete = <error>]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %x.patt: <error> = binding_pattern x [concrete]
// CHECK:STDOUT: %x.var_patt: <error> = var_pattern %x.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x.var: ref <error> = var %x.var_patt [concrete = <error>]
// CHECK:STDOUT: %MyStructAlias.ref: type = name_ref MyStructAlias, imports.%Main.MyStructAlias [concrete = <error>]
// CHECK:STDOUT: %x: <error> = bind_name x, <error> [concrete = <error>]
// CHECK:STDOUT: %x.ref: <error> = name_ref x, %x [concrete = <error>]
// CHECK:STDOUT: %Foo.ref: <error> = name_ref Foo, <error> [concrete = <error>]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_import_function_api.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {