Skip to content

Commit b19a325

Browse files
committed
[IRGen] Ensure that empty structs respect non-trivial destruction of members
An empty struct that is noncopyable can nonetheless have a `deinit`, so it is not trivially destructible. In such cases, embedded them in another empty struct means that the outer struct should also not be trivially destructible. Make it so.
1 parent caf78cd commit b19a325

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

lib/IRGen/StructLayout.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,10 @@ StructLayout::StructLayout(IRGenModule &IGM, std::optional<CanType> type,
178178
SpareBits.clear();
179179
IsFixedLayout = true;
180180
IsLoadable = true;
181-
IsKnownTriviallyDestroyable = deinit;
182-
IsKnownBitwiseTakable = IsBitwiseTakable;
183-
IsKnownAlwaysFixedSize = IsFixedSize;
184-
IsKnownCopyable = copyable;
181+
IsKnownTriviallyDestroyable = deinit & builder.isTriviallyDestroyable();
182+
IsKnownBitwiseTakable = builder.isBitwiseTakable();
183+
IsKnownAlwaysFixedSize = builder.isAlwaysFixedSize();
184+
IsKnownCopyable = copyable & builder.isCopyable();
185185
Ty = (typeToFill ? typeToFill : IGM.OpaqueTy);
186186
} else {
187187
MinimumAlign = builder.getAlignment();

test/IRGen/moveonly_deinits.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,18 @@ public func testKlassEnumPairWithDeinit() {
373373
consumeKlassEnumPairWithDeinit(f)
374374
}
375375
}
376+
377+
struct EmptyMoveOnlyWithDeinit: ~Copyable {
378+
deinit {}
379+
}
380+
381+
struct EnclosesEmptyMoveOnlyWithDeinit: ~Copyable {
382+
var stored: EmptyMoveOnlyWithDeinit
383+
}
384+
385+
// IR-LABEL: define {{.*}}swiftcc void @"$s16moveonly_deinits35testEnclosesEmptyMoveOnlyWithDeinityyF"()
386+
func testEnclosesEmptyMoveOnlyWithDeinit() {
387+
// CHECK-NOT: ret
388+
// CHECK: call swiftcc void @"$s16moveonly_deinits23EmptyMoveOnlyWithDeinitVfD"()
389+
_ = EnclosesEmptyMoveOnlyWithDeinit(stored: EmptyMoveOnlyWithDeinit())
390+
}

0 commit comments

Comments
 (0)