Skip to content

Commit 4cd76d9

Browse files
authored
Merge pull request #7985 from gottesmm/fix_ownership_forwarding_in_emitCastToReferenceType
2 parents 26ca022 + 9f1daaa commit 4cd76d9

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

lib/SILGen/SILGenBuilder.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,24 @@ ManagedValue SILGenBuilder::createTupleElementAddr(SILLocation Loc,
624624
return createTupleElementAddr(Loc, Value, Index, Type);
625625
}
626626

627+
ManagedValue SILGenBuilder::createUncheckedRefCast(SILLocation loc,
628+
ManagedValue value,
629+
SILType type) {
630+
CleanupCloner cloner(*this, value);
631+
SILValue cast =
632+
SILBuilder::createUncheckedRefCast(loc, value.forward(gen), type);
633+
return cloner.clone(cast);
634+
}
635+
636+
ManagedValue SILGenBuilder::createOpenExistentialRef(SILLocation loc,
637+
ManagedValue original,
638+
SILType type) {
639+
CleanupCloner cloner(*this, original);
640+
SILValue openedExistential =
641+
SILBuilder::createOpenExistentialRef(loc, original.forward(gen), type);
642+
return cloner.clone(openedExistential);
643+
}
644+
627645
//===----------------------------------------------------------------------===//
628646
// Switch Enum Builder
629647
//===----------------------------------------------------------------------===//

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,25 +325,21 @@ static ManagedValue emitCastToReferenceType(SILGenFunction &gen,
325325
SILValue undef = SILUndef::get(objPointerType, gen.SGM.M);
326326
return ManagedValue::forUnmanaged(undef);
327327
}
328-
329-
// Save the cleanup on the argument so we can forward it onto the cast
330-
// result.
331-
auto cleanup = args[0].getCleanup();
332-
333-
SILValue arg = args[0].getValue();
328+
329+
// Grab the argument.
330+
ManagedValue arg = args[0];
334331

335332
// If the argument is existential, open it.
336333
if (substitutions[0].getReplacement()->isClassExistentialType()) {
337334
auto openedTy
338335
= ArchetypeType::getOpened(substitutions[0].getReplacement());
339336
SILType loweredOpenedTy = gen.getLoweredLoadableType(openedTy);
340337
arg = gen.B.createOpenExistentialRef(loc, arg, loweredOpenedTy);
341-
gen.setArchetypeOpeningSite(openedTy, arg);
338+
gen.setArchetypeOpeningSite(openedTy, arg.getValue());
342339
}
343340

344-
SILValue result = gen.B.createUncheckedRefCast(loc, arg, objPointerType);
345-
// Return the cast result with the original cleanup.
346-
return ManagedValue(result, cleanup);
341+
// Return the cast result.
342+
return gen.B.createUncheckedRefCast(loc, arg, objPointerType);
347343
}
348344

349345
/// Specialized emitter for Builtin.castToNativeObject.

test/SILGen/builtins.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,28 @@ class C {}
181181
class D {}
182182

183183
// CHECK-LABEL: sil hidden @_T08builtins22class_to_native_object{{[_0-9a-zA-Z]*}}F
184+
// CHECK: bb0([[ARG:%.*]] : $C):
185+
// CHECK-NEXT: debug_value
186+
// CHECK-NEXT: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
187+
// CHECK-NEXT: [[COPY_BORROWED_ARG:%.*]] = copy_value [[BORROWED_ARG]]
188+
// CHECK-NEXT: [[OBJ:%.*]] = unchecked_ref_cast [[COPY_BORROWED_ARG:%.*]] to $Builtin.NativeObject
189+
// CHECK-NEXT: end_borrow [[BORROWED_ARG]] from [[ARG]]
190+
// CHECK-NEXT: destroy_value [[ARG]]
191+
// CHECK-NEXT: return [[OBJ]]
184192
func class_to_native_object(_ c:C) -> Builtin.NativeObject {
185-
// CHECK: [[OBJ:%.*]] = unchecked_ref_cast [[C:%.*]] to $Builtin.NativeObject
186-
// CHECK-NOT: destroy_value [[C]]
187-
// CHECK-NOT: destroy_value [[OBJ]]
188-
// CHECK: return [[OBJ]]
189193
return Builtin.castToNativeObject(c)
190194
}
191195

192196
// CHECK-LABEL: sil hidden @_T08builtins23class_to_unknown_object{{[_0-9a-zA-Z]*}}F
197+
// CHECK: bb0([[ARG:%.*]] : $C):
198+
// CHECK-NEXT: debug_value
199+
// CHECK-NEXT: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
200+
// CHECK-NEXT: [[COPY_BORROWED_ARG:%.*]] = copy_value [[BORROWED_ARG]]
201+
// CHECK-NEXT: [[OBJ:%.*]] = unchecked_ref_cast [[COPY_BORROWED_ARG:%.*]] to $Builtin.UnknownObject
202+
// CHECK-NEXT: end_borrow [[BORROWED_ARG]] from [[ARG]]
203+
// CHECK-NEXT: destroy_value [[ARG]]
204+
// CHECK-NEXT: return [[OBJ]]
193205
func class_to_unknown_object(_ c:C) -> Builtin.UnknownObject {
194-
// CHECK: [[OBJ:%.*]] = unchecked_ref_cast [[C:%.*]] to $Builtin.UnknownObject
195-
// CHECK-NOT: destroy_value [[C]]
196-
// CHECK-NOT: destroy_value [[OBJ]]
197-
// CHECK: return [[OBJ]]
198206
return Builtin.castToUnknownObject(c)
199207
}
200208

@@ -217,9 +225,16 @@ func class_archetype_to_unknown_object<T : C>(_ t: T) -> Builtin.UnknownObject {
217225
}
218226

219227
// CHECK-LABEL: sil hidden @_T08builtins34class_existential_to_native_object{{[_0-9a-zA-Z]*}}F
228+
// CHECK: bb0([[ARG:%.*]] : $ClassProto):
229+
// CHECK-NEXT: debug_value
230+
// CHECK-NEXT: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
231+
// CHECK-NEXT: [[COPY_BORROWED_ARG:%.*]] = copy_value [[BORROWED_ARG]]
232+
// CHECK-NEXT: [[REF:%[0-9]+]] = open_existential_ref [[COPY_BORROWED_ARG]] : $ClassProto
233+
// CHECK-NEXT: [[PTR:%[0-9]+]] = unchecked_ref_cast [[REF]] : $@opened({{.*}}) ClassProto to $Builtin.NativeObject
234+
// CHECK-NEXT: end_borrow [[BORROWED_ARG]] from [[ARG]]
235+
// CHECK-NEXT: destroy_value [[ARG]]
236+
// CHECK-NEXT: return [[PTR]]
220237
func class_existential_to_native_object(_ t:ClassProto) -> Builtin.NativeObject {
221-
// CHECK: [[REF:%[0-9]+]] = open_existential_ref [[T:%[0-9]+]] : $ClassProto
222-
// CHECK: [[PTR:%[0-9]+]] = unchecked_ref_cast [[REF]] : $@opened({{.*}}) ClassProto to $Builtin.NativeObject
223238
return Builtin.castToNativeObject(t)
224239
}
225240

0 commit comments

Comments
 (0)