Skip to content

Commit 37567b5

Browse files
committed
DefiniteInitialization: correctly handle upcasts in delegating initializers
Fixes a crash due to a wrong class type when creating a value_metatype instruction rdar://140926647
1 parent 3914d25 commit 37567b5

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,6 +2741,12 @@ void LifetimeChecker::processUninitializedRelease(SILInstruction *Release,
27412741
if (Pointer->getType().isAddress())
27422742
Pointer = B.createLoad(Loc, Pointer, LoadOwnershipQualifier::Take);
27432743

2744+
// Cast back down from an upcast.
2745+
if (auto *UI = dyn_cast<UpcastInst>(Pointer)) {
2746+
Pointer =
2747+
B.createUncheckedRefCast(Loc, Pointer, UI->getOperand()->getType());
2748+
}
2749+
27442750
auto MetatypeTy = CanMetatypeType::get(TheMemory.getASTType(),
27452751
MetatypeRepresentation::Thick);
27462752
auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
@@ -2763,12 +2769,6 @@ void LifetimeChecker::processUninitializedRelease(SILInstruction *Release,
27632769
}
27642770
}
27652771

2766-
// Cast back down from an upcast.
2767-
if (auto *UI = dyn_cast<UpcastInst>(Pointer)) {
2768-
Pointer =
2769-
B.createUncheckedRefCast(Loc, Pointer, UI->getOperand()->getType());
2770-
}
2771-
27722772
// We've already destroyed any instance variables initialized by this
27732773
// constructor, now destroy instance variables initialized by subclass
27742774
// constructors that delegated to us, and finally free the memory.

test/SILOptimizer/definite_init_crashes_objc.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class Sub : Super {
3737
// CHECK: switch_enum
3838
// CHECK-SAME: case #Optional.none!enumelt: [[NONE:bb[0-9]+]]
3939
// CHECK: [[NONE]]:
40-
// CHECK: [[SUB_META_1:%[^,]+]] = metatype $@thick Sub.Type
4140
// CHECK: [[SUB_1:%[^,]+]] = unchecked_ref_cast [[SUPER_1]] : $Super to $Sub
41+
// CHECK: [[SUB_META_1:%[^,]+]] = metatype $@thick Sub.Type
4242
// CHECK: dealloc_partial_ref
4343
// CHECK-SAME: [[SUB_1]]
4444
// CHECK-SAME: [[SUB_META_1]]

test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,31 @@ bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
148148
return %13 : $()
149149
}
150150

151+
// CHECK-LABEL: sil [ossa] @test_delegating_derived_with_upcast :
152+
// CHECK: bb0([[ARG:%.*]] : @owned $DerivedClassWithNontrivialStoredProperties):
153+
// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack $DerivedClassWithNontrivialStoredProperties
154+
// CHECK-NEXT: store [[ARG]] to [init] [[SELFBOX]]
155+
// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[SELFBOX]]
156+
// CHECK-NEXT: [[UC:%[0-9]+]] = upcast [[SELF]]
157+
// CHECK-NEXT: [[DC:%[0-9]+]] = unchecked_ref_cast [[UC]]
158+
// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick DerivedClassWithNontrivialStoredProperties.Type, [[DC]] : $DerivedClassWithNontrivialStoredProperties
159+
// CHECK-NEXT: dealloc_partial_ref [[DC]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type
160+
// CHECK-NEXT: dealloc_stack [[SELFBOX]]
161+
sil [ossa] @test_delegating_derived_with_upcast : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () {
162+
bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
163+
%1 = alloc_stack $DerivedClassWithNontrivialStoredProperties
164+
%2 = mark_uninitialized [delegatingselfallocated] %1 : $*DerivedClassWithNontrivialStoredProperties
165+
store %0 to [init] %2 : $*DerivedClassWithNontrivialStoredProperties
166+
%4 = load [take] %2 : $*DerivedClassWithNontrivialStoredProperties
167+
%5 = upcast %4 : $DerivedClassWithNontrivialStoredProperties to $RootClassWithNontrivialStoredProperties
168+
169+
destroy_value %5 : $RootClassWithNontrivialStoredProperties
170+
dealloc_stack %1 : $*DerivedClassWithNontrivialStoredProperties
171+
172+
%13 = tuple ()
173+
return %13 : $()
174+
}
175+
151176
// <rdar://problem/20608881> DI miscompiles this testcase into a memory leak
152177
struct MyStruct3 {
153178
@_hasStorage var c: C

0 commit comments

Comments
 (0)