Skip to content

Commit 4483d1e

Browse files
zygoloiddanakj
andauthored
Recover better from invalid C++ classes. (#5992)
When importing a class definition, don't ask for the class layout if the definition is invalid. Avoids an assertion failure in Clang. --------- Co-authored-by: Dana Jansens <[email protected]>
1 parent 00d0eb8 commit 4483d1e

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

toolchain/check/import_cpp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,11 @@ static auto ImportClassObjectRepr(Context& context, SemIR::ClassId class_id,
825825
SemIR::TypeInstId class_type_inst_id,
826826
const clang::CXXRecordDecl* clang_def)
827827
-> SemIR::TypeInstId {
828+
if (clang_def->isInvalidDecl()) {
829+
// Clang already diagnosed this error.
830+
return SemIR::ErrorInst::TypeInstId;
831+
}
832+
828833
// For now, if the class is empty, produce an empty struct as the object
829834
// representation. This allows our tests to continue to pass while we don't
830835
// properly support initializing imported C++ classes.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
2+
// Exceptions. See /LICENSE for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
//
5+
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
6+
//
7+
// AUTOUPDATE
8+
// TIP: To test this file alone, run:
9+
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/class/invalid.carbon
10+
// TIP: To dump output, run:
11+
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/class/invalid.carbon
12+
13+
// --- fail_invalid_base.carbon
14+
15+
library "[[@TEST_NAME]]";
16+
17+
import Cpp inline '''
18+
struct Base {
19+
// CHECK:STDERR: fail_invalid_base.carbon:[[@LINE+4]]:3: error: unknown type name 'no_such_type' [CppInteropParseError]
20+
// CHECK:STDERR: 10 | no_such_type invalid;
21+
// CHECK:STDERR: | ^
22+
// CHECK:STDERR:
23+
no_such_type invalid;
24+
};
25+
26+
struct Derived : Base {};
27+
''';
28+
29+
// Use of an invalid class should not cause the toolchain to crash or produce
30+
// redundant diagnostics.
31+
var x: Cpp.Derived;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
2+
// Exceptions. See /LICENSE for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
//
5+
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
6+
//
7+
// AUTOUPDATE
8+
// TIP: To test this file alone, run:
9+
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/enum/invalid.carbon
10+
// TIP: To dump output, run:
11+
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/enum/invalid.carbon
12+
13+
// --- fail_invalid_underlying_type.carbon
14+
15+
library "[[@TEST_NAME]]";
16+
17+
import Cpp inline '''
18+
// CHECK:STDERR: fail_invalid_underlying_type.carbon:[[@LINE+4]]:20: error: unknown type name 'no_such_type' [CppInteropParseError]
19+
// CHECK:STDERR: 9 | enum InvalidEnum : no_such_type {};
20+
// CHECK:STDERR: | ^
21+
// CHECK:STDERR:
22+
enum InvalidEnum : no_such_type {};
23+
''';
24+
25+
// Use of an invalid enum should not cause the toolchain to crash or produce
26+
// redundant diagnostics.
27+
var x: Cpp.InvalidEnum;

0 commit comments

Comments
 (0)