Skip to content

Commit 65adc5a

Browse files
committed
FunctionSignatureOpts: don't convert non-copyable owned -> guaranteed arguments
It's not safe to insert a compensating release_value at the call site. This release_value calls the deinit which might have been already de-virtualized in the callee.
1 parent a07caa8 commit 65adc5a

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/SILOptimizer/FunctionSignatureTransforms/OwnedToGuaranteedTransform.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeParameters() {
8080
if (!A.canOptimizeLiveArg()) {
8181
continue;
8282
}
83+
if (A.Arg->getType().isMoveOnly()) {
84+
// We must not do this transformation for non-copyable types, because it's
85+
// not safe to insert a compensating release_value at the call site. This
86+
// release_value calls the deinit which might have been already de-
87+
// virtualized in the callee.
88+
continue;
89+
}
8390

8491
// See if we can find a ref count equivalent strong_release or release_value
8592
// at the end of this function if our argument is an @owned parameter.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-run-simple-swift(-enable-experimental-feature Embedded -O -parse-as-library -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: OS=macosx || OS=linux-gnu
5+
6+
var deinitCalled = false
7+
8+
struct S: ~Copyable {
9+
let s: String
10+
11+
@inline(never)
12+
deinit {
13+
precondition(!deinitCalled)
14+
deinitCalled = true
15+
print(s)
16+
}
17+
}
18+
19+
@main
20+
struct Main {
21+
static func main() {
22+
// CHECK: 1
23+
_ = S(s: "1")
24+
// CHECK-NEXT: done
25+
print("done")
26+
}
27+
}
28+

0 commit comments

Comments
 (0)