Skip to content

Commit 7246806

Browse files
committed
When emitting no-escape closures, make sure that we copy the closure before we pass it into the partial apply to eliminate an ownership violation.
The problem here is that without this patch we emit code like this: bb0(%0 : @owned $T): %1 = partial_apply %foo(%0) %2 = mark_dependence %1 on %0 Since a partial_apply consumes the object, the mark_dependence is a use after free (especially if one has any further uses of %0 after the mark_dependence). So what I did was I copied the value before creating the partial_apply. So now we get this: bb0(%0 : @owned $T): %1 = copy_value %0 %2 = partial_apply %foo(%1) %3 = mark_dependence %2 on %0 ... destroy_value %0 This ensures that one can actually have uses after the mark_dependence of both operands. This enables ownership verification to be enabled on Interpreter/enforce_exclusive_access. rdar://48521061
1 parent 0680ce1 commit 7246806

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,17 +3327,20 @@ SILGenFunction::createWithoutActuallyEscapingClosure(
33273327

33283328
// Create it in our current function.
33293329
auto thunkValue = B.createFunctionRefFor(loc, thunk);
3330+
3331+
// Create a copy for the noescape value, so we can mark_dependence upon the
3332+
// original value.
33303333
SILValue noEscapeValue =
3331-
noEscapingFunctionValue.ensurePlusOne(*this, loc).forward(*this);
3334+
noEscapingFunctionValue.copy(*this, loc).forward(*this);
33323335
SingleValueInstruction *thunkedFn = B.createPartialApply(
33333336
loc, thunkValue,
33343337
SILType::getPrimitiveObjectType(substFnTy),
33353338
interfaceSubs,
33363339
noEscapeValue,
33373340
SILType::getPrimitiveObjectType(escapingFnTy));
33383341
// We need to ensure the 'lifetime' of the trivial values context captures. As
3339-
// long as we rerpresent these captures by the same value the following works.
3340-
thunkedFn = B.createMarkDependence(loc, thunkedFn, noEscapeValue);
3342+
// long as we represent these captures by the same value the following works.
3343+
thunkedFn = B.createMarkDependence(loc, thunkedFn, noEscapingFunctionValue.getValue());
33413344

33423345
return emitManagedRValueWithCleanup(thunkedFn);
33433346
}

test/Interpreter/enforce_exclusive_access.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-build-swift -swift-version 4 %s -o %t/a.out -enforce-exclusivity=checked -Onone
2+
// RUN: %target-build-swift -Xfrontend -verify-sil-ownership -swift-version 4 %s -o %t/a.out -enforce-exclusivity=checked -Onone
33
//
44
// RUN: %target-codesign %t/a.out
55
// RUN: %target-run %t/a.out

0 commit comments

Comments
 (0)