Skip to content

Commit e619220

Browse files
committed
avoid generating explicit_copy_* for copyable types
The move checker was converting some kinds of copies into their `explicit_copy_*` versions, despite the type of the copy being a copyable type. This was causing random crashes in some narrow circumstances. resolves rdar://106669967
1 parent 96cf38a commit e619220

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyUtils.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,12 @@ bool swift::siloptimizer::cleanupNonCopyableCopiesAfterEmittingDiagnostic(
116116
auto *inst = &*ii;
117117
++ii;
118118

119-
// Convert load [copy] -> load_borrow + explicit_copy_value.
119+
// Convert load [copy] *MoveOnly -> load_borrow + explicit_copy_value.
120120
if (auto *li = dyn_cast<LoadInst>(inst)) {
121121
if (li->getOwnershipQualifier() == LoadOwnershipQualifier::Copy) {
122+
if (!li->getType().isMoveOnly())
123+
continue;
124+
122125
SILBuilderWithScope builder(li);
123126
auto *lbi = builder.createLoadBorrow(li->getLoc(), li->getOperand());
124127
auto *cvi = builder.createExplicitCopyValue(li->getLoc(), lbi);
@@ -129,10 +132,13 @@ bool swift::siloptimizer::cleanupNonCopyableCopiesAfterEmittingDiagnostic(
129132
}
130133
}
131134

132-
// Convert copy_addr !take of src to its explicit value form so we don't
133-
// error.
135+
// Convert copy_addr !take MoveOnly ... -> explicit_copy_addr ...same...
136+
// so we don't error.
134137
if (auto *copyAddr = dyn_cast<CopyAddrInst>(inst)) {
135138
if (!copyAddr->isTakeOfSrc()) {
139+
if (!copyAddr->getSrc()->getType().isMoveOnly())
140+
continue;
141+
136142
SILBuilderWithScope builder(copyAddr);
137143
builder.createExplicitCopyAddr(
138144
copyAddr->getLoc(), copyAddr->getSrc(), copyAddr->getDest(),
@@ -143,10 +149,11 @@ bool swift::siloptimizer::cleanupNonCopyableCopiesAfterEmittingDiagnostic(
143149
}
144150
}
145151

146-
// Convert any copy_value of move_only type to explicit copy value.
152+
// Convert any copy_value of MoveOnly type -> explicit_copy_value.
147153
if (auto *cvi = dyn_cast<CopyValueInst>(inst)) {
148154
if (!cvi->getOperand()->getType().isMoveOnly())
149155
continue;
156+
150157
SILBuilderWithScope b(cvi);
151158
auto *expCopy =
152159
b.createExplicitCopyValue(cvi->getLoc(), cvi->getOperand());

test/IRGen/struct_resilience.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,3 +339,8 @@ public func memoryLayoutDotOffsetOfWithResilientStruct() -> Int? {
339339
// CHECK: store i8** [[SIZE_AND_ALIGNMENT:%.*]], i8*** [[FIELD_4]]
340340

341341
// CHECK: call void @swift_initStructMetadata(%swift.type* {{.*}}, [[INT]] 256, [[INT]] 4, i8*** [[FIELDS_ADDR]], i32* {{.*}})
342+
343+
// coverage for rdar://106669967 where a SIL crash can happen under `-enable-library-evolution -O`
344+
public struct StructWithResilientInit {
345+
public init() {}
346+
}

0 commit comments

Comments
 (0)