| // RUN: %target-run-simple-swift | %FileCheck %s |
| // REQUIRES: executable_test |
| |
| // REQUIRES: objc_interop |
| |
| // The Objective-C runtime does not implement the autorelease |
| // optimization on i386, even in the iOS simulator. |
| // XFAIL: CPU=i386 |
| |
| import Foundation |
| |
| class PrintOnDeinit: NSObject { |
| // Result should get autoreleased. |
| @objc dynamic class func create() -> PrintOnDeinit { |
| return PrintOnDeinit() |
| } |
| |
| deinit { print("object died") } |
| } |
| func useTemp() { |
| let f = PrintOnDeinit.create() |
| } |
| |
| // objc_retainAutoreleasedReturnValue will fail to reclaim the first |
| // object autoreleased from each shared object on x86_64, so prime it. |
| autoreleasepool { useTemp() } |
| autoreleasepool { |
| print("autorelease test begin") |
| useTemp() |
| print("after call to useTemp") |
| } |
| print("autorelease test end") |
| // CHECK: autorelease test begin |
| // CHECK-NEXT: object died |
| // CHECK-NEXT: after call to useTemp |
| // CHECK-NEXT: autorelease test end |
| |
| // Using an @objc class to check that errors are retained across the pool |
| // boundaries. A classic crash is an error created inside a pool and then |
| // zombied before handling it outside the pool. |
| @objc class MyError : NSObject, Error { |
| let message: String |
| init(message: String) { |
| self.message = message |
| } |
| } |
| |
| // Check that rethrow works. |
| func requireString(string: String?) throws -> String { |
| guard let string = string else { |
| throw MyError(message: "no string") |
| } |
| print("returning \"\(string)\"") |
| return string |
| } |
| do { |
| try autoreleasepool { |
| try requireString(string: "ok") |
| try requireString(string: nil) |
| } |
| } catch let err as MyError { |
| print("caught \"\(err.message)\"") |
| } |
| // CHECK-NEXT: returning "ok" |
| // CHECK-NEXT: caught "no string" |
| |
| // Check that a return value can be passed back. |
| let result = try autoreleasepool { |
| return "a string" |
| } |
| print("result = \"\(result)\"") |
| // CHECK-NEXT: result = "a string" |