Skip to content

Commit 8ae1f92

Browse files
authored
Merge pull request #7621 from gottesmm/unmanaged_retainreleaseautorelease
2 parents 4908e84 + 850e674 commit 8ae1f92

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ static ManagedValue emitBuiltinRetain(SILGenFunction &gen,
6969
ArrayRef<ManagedValue> args,
7070
CanFunctionType formalApplyType,
7171
SGFContext C) {
72-
// The value was produced at +1; we can produce an unbalanced
73-
// retain simply by disabling the cleanup.
74-
args[0].forward(gen);
72+
// The value was produced at +1; we can produce an unbalanced retain simply by
73+
// disabling the cleanup. But this would violate ownership semantics. Instead,
74+
// we must allow for the cleanup and emit a new unmanaged retain value.
75+
gen.B.createUnmanagedRetainValue(loc, args[0].getValue());
7576
return ManagedValue::forUnmanaged(gen.emitEmptyTuple(loc));
7677
}
7778

@@ -84,7 +85,7 @@ static ManagedValue emitBuiltinRelease(SILGenFunction &gen,
8485
// The value was produced at +1, so to produce an unbalanced
8586
// release we need to leave the cleanup intact and then do a *second*
8687
// release.
87-
gen.B.createDestroyValue(loc, args[0].getValue());
88+
gen.B.createUnmanagedReleaseValue(loc, args[0].getValue());
8889
return ManagedValue::forUnmanaged(gen.emitEmptyTuple(loc));
8990
}
9091

@@ -94,9 +95,7 @@ static ManagedValue emitBuiltinAutorelease(SILGenFunction &gen,
9495
ArrayRef<ManagedValue> args,
9596
CanFunctionType formalApplyType,
9697
SGFContext C) {
97-
// The value was produced at +1, so to produce an unbalanced
98-
// autorelease we need to leave the cleanup intact.
99-
gen.B.createAutoreleaseValue(loc, args[0].getValue(), Atomicity::Atomic);
98+
gen.B.createUnmanagedAutoreleaseValue(loc, args[0].getValue());
10099
return ManagedValue::forUnmanaged(gen.emitEmptyTuple(loc));
101100
}
102101

test/SILGen/builtins.swift

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ func assumeNonNegative(_ x: Builtin.Word) -> Builtin.Word {
511511
// CHECK: bb0([[ARG:%.*]] : $O):
512512
// CHECK: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
513513
// CHECK: [[ARG_COPY:%.*]] = copy_value [[BORROWED_ARG]]
514-
// CHECK: autorelease_value [[ARG_COPY]]
514+
// CHECK: unmanaged_autorelease_value [[ARG_COPY]]
515515
// CHECK: destroy_value [[ARG_COPY]]
516516
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]]
517517
// CHECK: destroy_value [[ARG]]
@@ -866,3 +866,56 @@ func unsafeGuaranteedEnd(_ t: Builtin.Int8) {
866866
func bindMemory<T>(ptr: Builtin.RawPointer, idx: Builtin.Word, _: T.Type) {
867867
Builtin.bindMemory(ptr, idx, T.self)
868868
}
869+
870+
//===----------------------------------------------------------------------===//
871+
// RC Operations
872+
//===----------------------------------------------------------------------===//
873+
874+
// SILGen test:
875+
//
876+
// CHECK-LABEL: sil hidden @_T08builtins6retain{{[_0-9a-zA-Z]*}}F : $@convention(thin) (@owned Builtin.NativeObject) -> () {
877+
// CHECK: bb0([[P:%.*]] : $Builtin.NativeObject):
878+
// CHECK: [[BORROWED_P:%.*]] = begin_borrow [[P]]
879+
// CHECK: [[COPIED_P:%.*]] = copy_value [[BORROWED_P]]
880+
// CHECK: unmanaged_retain_value [[COPIED_P]]
881+
// CHECK: destroy_value [[COPIED_P]]
882+
// CHECK: end_borrow [[BORROWED_P]] from [[P]]
883+
// CHECK: destroy_value [[P]]
884+
// CHECK: } // end sil function '_T08builtins6retain{{[_0-9a-zA-Z]*}}F'
885+
886+
// SIL Test. This makes sure that we properly clean up in -Onone SIL.
887+
// CANONICAL-LABEL: sil hidden @_T08builtins6retain{{[_0-9a-zA-Z]*}}F : $@convention(thin) (@owned Builtin.NativeObject) -> () {
888+
// CANONICAL: bb0([[P:%.*]] : $Builtin.NativeObject):
889+
// CANONICAL-NOT: retain
890+
// CANONICAL-NOT: release
891+
// CANONICAL: } // end sil function '_T08builtins6retain{{[_0-9a-zA-Z]*}}F'
892+
func retain(ptr: Builtin.NativeObject) {
893+
Builtin.retain(ptr)
894+
}
895+
896+
// SILGen test:
897+
//
898+
// CHECK-LABEL: sil hidden @_T08builtins7release{{[_0-9a-zA-Z]*}}F : $@convention(thin) (@owned Builtin.NativeObject) -> () {
899+
// CHECK: bb0([[P:%.*]] : $Builtin.NativeObject):
900+
// CHECK: [[BORROWED_P:%.*]] = begin_borrow [[P]]
901+
// CHECK: [[COPIED_P:%.*]] = copy_value [[BORROWED_P]]
902+
// CHECK: unmanaged_release_value [[COPIED_P]]
903+
// CHECK: destroy_value [[COPIED_P]]
904+
// CHECK: end_borrow [[BORROWED_P]] from [[P]]
905+
// CHECK: destroy_value [[P]]
906+
// CHECK: } // end sil function '_T08builtins7release{{[_0-9a-zA-Z]*}}F'
907+
908+
// SIL Test. Make sure even in -Onone code, we clean this up properly:
909+
// CANONICAL-LABEL: sil hidden @_T08builtins7release{{[_0-9a-zA-Z]*}}F : $@convention(thin) (@owned Builtin.NativeObject) -> () {
910+
// CANONICAL: bb0([[P:%.*]] : $Builtin.NativeObject):
911+
// CANONICAL-NEXT: debug_value
912+
// CANONICAL-NEXT: tuple
913+
// CANONICAL-NEXT: strong_release [[P]]
914+
// CANONICAL-NEXT: strong_release [[P]]
915+
// CANONICAL-NEXT: tuple
916+
// CANONICAL-NEXT: return
917+
// CANONICAL: } // end sil function '_T08builtins7release{{[_0-9a-zA-Z]*}}F'
918+
919+
func release(ptr: Builtin.NativeObject) {
920+
Builtin.release(ptr)
921+
}

0 commit comments

Comments
 (0)