mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
fix: reject {} initialization for non-aggregate C++ classes (#6675)
## Summary
Fixes the toolchain incorrectly allowing `{}` initialization for
non-aggregate C++ classes.
## Problem
When importing an empty C++ class, the toolchain was treating it as a
Carbon empty struct, which allowed initialization from `{}`. This is
incorrect for non-aggregate classes (e.g., those with user-declared
constructors).
```carbon
import Cpp inline '''
struct X { X(); }; // non-aggregate (has user-declared constructor)
''';
fn Make() {
var x: Cpp.X = {}; // incorrectly accepted, should be rejected
}
```
## Solution
Added a check for `clang_def->isAggregate()` in `ImportClassObjectRepr`
so that only aggregate classes get the empty struct representation.
**Before:**
```cpp
if (clang_def->isEmpty() && !clang_def->getNumBases()) {
```
**After:**
```cpp
if (clang_def->isEmpty() && !clang_def->getNumBases() &&
clang_def->isAggregate()) {
```
## Testing
Added test file
`toolchain/check/testdata/interop/cpp/class/non_aggregate_init.carbon`
with:
- Non-aggregate class (`struct X { X(); }`) - should reject `{}`
initialization
- Aggregate class (`struct Y {}`) - should accept `{}` initialization
Note: I couldn't run tests locally due to clang version requirements
(needs >= 19, have 17). The CI should validate the changes.
Closes #6669
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
9915e155a3
commit
8edd5eb9a1
@@ -429,11 +429,14 @@ static auto ImportClassObjectRepr(Context& context, SemIR::ClassId class_id,
|
||||
return SemIR::ErrorInst::TypeInstId;
|
||||
}
|
||||
|
||||
// For now, if the class is empty, produce an empty struct as the object
|
||||
// representation. This allows our tests to continue to pass while we don't
|
||||
// properly support initializing imported C++ classes.
|
||||
// For now, if the class is empty and an aggregate, produce an empty struct as
|
||||
// the object representation. This allows our tests to continue to pass while
|
||||
// we don't properly support initializing imported C++ classes. We only do
|
||||
// this for aggregates so that non-aggregate classes are not incorrectly
|
||||
// initializable from `{}`.
|
||||
// TODO: Remove this.
|
||||
if (clang_def->isEmpty() && !clang_def->getNumBases()) {
|
||||
if (clang_def->isEmpty() && !clang_def->getNumBases() &&
|
||||
clang_def->isAggregate()) {
|
||||
return context.types().GetAsTypeInstId(AddInst(
|
||||
context,
|
||||
MakeImportedLocIdAndInst(
|
||||
|
||||
Reference in New Issue
Block a user