Files
swift-mirror/test/SILOptimizer/arc_crash.swift
Andrew Trick 23696e4dff Fix EscapeAnalysis::mayReleaseContent
The previous implementation made extremely subtle and specific
assumptions about how the API is used which doesn't apply
everywhere. It was trying very hard to avoid regressing performance
relative to an even older implementation that didn't even try to consider deinitializer side effects.

The aggressive logic was based on the idea that a release must have a
corresponding retain somewhere in the same function and we don't care
if the last release happens early if there are no more aliasing
uses. All the unit tests I wrote previously were based on release
hoisting, which happens to work given the way the API is used.

But this logic is incorrect for retain sinking. In that case sinking
past an "unrelated" release could cause the object to be freed
early. See test/SILOptimizer/arc_crash.swift.

With SemanticARC and other SIL improvements being made, I'm afraid
bugs like this will begin to surface.

To fix it, just remove the subtle logic to leave behind a simple and
sound EscapeAnalysis API. To do better, we will need to rewrite the
AliasAnalysis logic for release side effects, which is currently
a tangled web. In the meantime, SemanticARC can handle many cases without EscapeAnalysis.

Fixes rdar://74469299 (ARC miscompile:
EscapeAnalysis::mayReleaseContent; potential use-after-free)

While fixing this, add support for address-type queries too:

Fixes rdar://74360041 (Assertion failed:
(!releasedReference->getType().isAddress() && "an address is never a
reference"), function mayReleaseContent
2021-02-18 19:00:22 -08:00

51 lines
1.5 KiB
Swift

// RUN: %target-swift-frontend -O %s -parse-as-library -emit-sil -enforce-exclusivity=none -Xllvm -sil-disable-pass=function-signature-opts | %FileCheck %s
// Test ARC optimizations on source level tests that have been
// miscompiled and crash (e.g. because of use-after-free).
// -----------------------------------------------------------------------------
// rdar://74469299 (ARC miscompile: EscapeAnalysis::mayReleaseContent;
// potential use-after-free)
// -----------------------------------------------------------------------------
public class Base {
var i = 3
init() {}
}
public class Node : Base {
var node: Base
init(node: Base) { self.node = node }
}
struct Queue {
var node: Node
}
@inline(never)
func useQueue(q: __owned Queue) {}
@inline(never)
func useNode(n: Base) -> Int {
return n.i
}
// CHECK-LABEL: sil [noinline] @$s9arc_crash14testMayReleaseAA4BaseCyF : $@convention(thin) () -> @owned Base {
// CHECK: [[BASE:%.*]] = alloc_ref $Base
// CHECK: strong_retain [[BASE]] : $Base
// CHECK: apply %{{.*}} : $@convention(thin) (@owned Queue) -> ()
// CHECK-LABEL: } // end sil function '$s9arc_crash14testMayReleaseAA4BaseCyF'
@inline(never)
public func testMayRelease() -> Base {
let n2 = Base()
let n1 = Node(node: n2)
let q = Queue(node: n1)
// n2 must not be release before useQueue.
useQueue(q: q)
return n2
}
// This crashes when testMayRelease releases the object too early.
// print("Object:")
// print(testMayRelease())
// -----------------------------------------------------------------------------