Skip to content

Commit 881351b

Browse files
committed
FunctionSignatureOptimization: don't convert indirect @in to @in_guaranteed if the argument is mutated
This fixes a verifier error because an `@in_guaranteed` argument must not be mutated. #81444 rdar://151147971
1 parent 21303a5 commit 881351b

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/SILOptimizer/FunctionSignatureTransforms/OwnedToGuaranteedTransform.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeParameters() {
8888
continue;
8989
}
9090

91+
// Make sure that an @in argument is not mutated otherwise than destroyed,
92+
// because an @in_guaranteed argument must not be mutated.
93+
if (A.hasConvention(SILArgumentConvention::Indirect_In) &&
94+
// With opaque values, @in arguments can have non-address types.
95+
A.Arg->getType().isAddress() &&
96+
isIndirectArgumentMutated(A.Arg, /*ignoreDestroys=*/ true, /*defaultIsMutating=*/true)) {
97+
continue;
98+
}
99+
91100
// See if we can find a ref count equivalent strong_release or release_value
92101
// at the end of this function if our argument is an @owned parameter.
93102
// See if we can find a destroy_addr at the end of this function if our

test/SILOptimizer/functionsigopts_crash.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,21 @@ func testit(_ p: P) {
3535
public func callit(s: S) {
3636
testit(s)
3737
}
38+
39+
// Check that FSO does not trigger a verifier error caused by a mutated @in argument which is
40+
// converted to an @in_guaranteed argument (which must not be mutated).
41+
42+
public protocol IP<Element> {
43+
associatedtype Element
44+
45+
init<Iterator>(iterator: consuming Iterator) where Iterator: IteratorProtocol, Iterator.Element == Element
46+
}
47+
48+
extension Array: IP {
49+
public init<Iterator>(iterator: consuming Iterator) where Iterator: IteratorProtocol, Iterator.Element == Element {
50+
self.init()
51+
while let next = iterator.next() {
52+
append(next)
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)