Files
swift-mirror/test/SILOptimizer/access_enforcement_selection.swift
2017-04-14 18:28:37 -07:00

68 lines
2.6 KiB
Swift

// RUN: %target-swift-frontend -enforce-exclusivity=checked -Onone -emit-sil -parse-as-library %s -Xllvm -debug-only=access-enforcement-selection 2>&1 | %FileCheck %s
// REQUIRES: asserts
// This is a source-level test because it helps bring up the entire -Onone pipeline with the access markers.
public func takesInout(_ i: inout Int) {
i = 42
}
// CHECK-LABEL: Access Enforcement Selection in _T028access_enforcement_selection10takesInoutySizF
// CHECK: Static Access: %{{.*}} = begin_access [modify] [static] %0 : $*Int
// Helper taking a basic, no-escape closure.
func takeClosure(_: ()->Int) {}
// Generate an alloc_stack that escapes into a closure.
public func captureStack() -> Int {
// Use a `var` so `x` isn't treated as a literal.
var x = 3
takeClosure { return x }
return x
}
// CHECK-LABEL: Access Enforcement Selection in _T028access_enforcement_selection12captureStackSiyF
// Static access for `return x`.
// CHECK: Static Access: %{{.*}} = begin_access [read] [static] %0 : $*Int
// The access inside the closure is dynamic, until we have the logic necessary to
// prove that no other closures are passed to `takeClosure` that may write to
// `x`.
//
// CHECK-LABEL: Access Enforcement Selection in _T028access_enforcement_selection12captureStackSiyFSiycfU_
// CHECK: Dynamic Access: %{{.*}} = begin_access [read] [dynamic] %0 : $*Int
// Generate a closure in which the @inout_aliasing argument
// escapes to an @inout function `bar`.
public func recaptureStack() -> Int {
var x = 3
takeClosure { takesInout(&x); return x }
return x
}
// CHECK-LABEL: Access Enforcement Selection in _T028access_enforcement_selection14recaptureStackSiyF
//
// Static access for `return x`.
// CHECK: Static Access: %10 = begin_access [read] [static] %0 : $*Int
// CHECK-LABEL: Access Enforcement Selection in _T028access_enforcement_selection14recaptureStackSiyFSiycfU_
//
// The first [modify] access inside the closure must be dynamic. It enforces the
// @inout argument.
// CHECK: Dynamic Access: %{{.*}} = begin_access [modify] [dynamic] %0 : $*Int
//
// The second [read] access is only dynamic because the analysis isn't strong
// enough to prove otherwise. Same as `captureStack` above.
//
// CHECK: Dynamic Access: %{{.*}} = begin_access [read] [dynamic] %0 : $*Int
public func undefStack(i: Int) -> Int {
_preconditionFailure("unreachable")
var x = 3
if i != 0 {
x = 42
}
return x
}
// CHECK-LABEL: Access Enforcement Selection in _T028access_enforcement_selection10undefStackS2i1i_tF
// CHECK: Static Access: %{{.*}} = begin_access [modify] [static] undef : $*Int
// CHECK: Static Access: %{{.*}} = begin_access [read] [static] undef : $*Int