// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -import-objc-header %S/Inputs/globals.h -emit-silgen %s | %FileCheck %s // REQUIRES: objc_interop // This test makes sure loading from globals properly retains/releases loads from globals. // NSString was the only real problem, as the compiler treats NSString globals specially. // The rest of these are just hedges against future changes. // From header: // globalString: __strong NSString* // globalObject: __strong NSObject* // globalID: __strong id // globalArray: __strong NSArray* // globalConstArray: __strong NSArray *const func main() { Globals.sharedInstance() // Initialize globals (dispatch_once) // CHECK: global_addr @globalConstArray : $*Optional // CHECK: global_addr @globalArray : $*Optional // CHECK: global_addr @globalId : $*Optional // CHECK: global_addr @globalObject : $*Optional // CHECK: global_addr @globalString : $*NSString // CHECK: [[globalString:%.*]] = load [copy] {{%.*}} : $*NSString // CHECK: [[bridgeStringFunc:%.*]] = function_ref @{{.*}} : $@convention(method) (@owned Optional, @thin String.Type) -> @owned String // CHECK: [[wrappedString:%.*]] = enum $Optional, #Optional.some!enumelt.1, [[globalString]] : $NSString // CHECK: [[stringMetaType:%.*]] = metatype $@thin String.Type // CHECK: [[bridgedString:%.*]] = apply [[bridgeStringFunc]]([[wrappedString]], [[stringMetaType]]) : $@convention(method) (@owned Optional, @thin String.Type) -> @owned String let string = globalString // Problematic case, wasn't being retained // CHECK: [[load_1:%.*]] = load [copy] {{%.*}} : $*Optional let object = globalObject // CHECK: [[load_2:%.*]] = load [copy] {{%.*}} : $*Optional let id = globalId // CHECK: [[load_3:%.*]] = load [copy] {{%.*}} : $*Optional let arr = globalArray // CHECK: [[load_4:%.*]] = load [copy] {{%.*}} : $*Optional let constArr = globalConstArray // Make sure there's no more copies // CHECK-NOT: load [copy] print(string as Any) print(object as Any) print(id as Any) print(arr as Any) print(constArr as Any) // CHECK: [[PRINT_FUN:%.*]] = function_ref @_T0s5printySayypGd_SS9separatorSS10terminatortF : $@convention(thin) (@owned Array, @owned String, @owned String) -> () // CHECK: apply [[PRINT_FUN]]({{.*}}) // CHECK: destroy_value [[load_4]] // CHECK: destroy_value [[load_3]] // CHECK: destroy_value [[load_2]] // CHECK: destroy_value [[load_1]] // CHECK: destroy_value [[bridgedString]] // Make sure there's no more destroys // CHECK-NOT: destroy_value // CHECK: } // end sil function '_T017retaining_globals4mainyyF' } main() main() // Used to crash here, due to use-after-free. main() main() main() main()