// RUN: %target-swift-emit-silgen -module-name pointer_conversion -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -enable-objc-interop | %FileCheck %s // FIXME: rdar://problem/19648117 Needs splitting objc parts out // REQUIRES: objc_interop import Foundation func sideEffect1() -> Int { return 1 } func sideEffect2() -> Int { return 2 } func takesMutablePointer(_ x: UnsafeMutablePointer) {} func takesConstPointer(_ x: UnsafePointer) {} func takesOptConstPointer(_ x: UnsafePointer?, and: Int) {} func takesOptOptConstPointer(_ x: UnsafePointer??, and: Int) {} func takesMutablePointer(_ x: UnsafeMutablePointer, and: Int) {} func takesConstPointer(_ x: UnsafePointer, and: Int) {} func takesMutableVoidPointer(_ x: UnsafeMutableRawPointer) {} func takesConstVoidPointer(_ x: UnsafeRawPointer) {} func takesMutableRawPointer(_ x: UnsafeMutableRawPointer) {} func takesConstRawPointer(_ x: UnsafeRawPointer) {} func takesOptConstRawPointer(_ x: UnsafeRawPointer?, and: Int) {} func takesOptOptConstRawPointer(_ x: UnsafeRawPointer??, and: Int) {} // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion0A9ToPointeryySpySiG_SPySiGSvtF // CHECK: bb0([[MP:%.*]] : $UnsafeMutablePointer, [[CP:%.*]] : $UnsafePointer, [[MRP:%.*]] : $UnsafeMutableRawPointer): func pointerToPointer(_ mp: UnsafeMutablePointer, _ cp: UnsafePointer, _ mrp: UnsafeMutableRawPointer) { // There should be no conversion here takesMutablePointer(mp) // CHECK: [[TAKES_MUTABLE_POINTER:%.*]] = function_ref @$s18pointer_conversion19takesMutablePointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE_POINTER]]([[MP]]) takesMutableVoidPointer(mp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafeMutableRawPointer> // CHECK: [[TAKES_MUTABLE_VOID_POINTER:%.*]] = function_ref @$s18pointer_conversion23takesMutableVoidPointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE_VOID_POINTER]] takesMutableRawPointer(mp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafeMutableRawPointer> // CHECK: [[TAKES_MUTABLE_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion22takesMutableRawPointeryySvF : // CHECK: apply [[TAKES_MUTABLE_RAW_POINTER]] takesConstPointer(mp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafePointer> // CHECK: [[TAKES_CONST_POINTER:%.*]] = function_ref @$s18pointer_conversion17takesConstPointeryySPySiGF // CHECK: apply [[TAKES_CONST_POINTER]] takesConstVoidPointer(mp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafeRawPointer> // CHECK: [[TAKES_CONST_VOID_POINTER:%.*]] = function_ref @$s18pointer_conversion21takesConstVoidPointeryySVF // CHECK: apply [[TAKES_CONST_VOID_POINTER]] takesConstRawPointer(mp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafeRawPointer> // CHECK: [[TAKES_CONST_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion20takesConstRawPointeryySVF : // CHECK: apply [[TAKES_CONST_RAW_POINTER]] takesConstPointer(cp) // CHECK: [[TAKES_CONST_POINTER:%.*]] = function_ref @$s18pointer_conversion17takesConstPointeryySPySiGF // CHECK: apply [[TAKES_CONST_POINTER]]([[CP]]) takesConstVoidPointer(cp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafeRawPointer> // CHECK: [[TAKES_CONST_VOID_POINTER:%.*]] = function_ref @$s18pointer_conversion21takesConstVoidPointeryySVF // CHECK: apply [[TAKES_CONST_VOID_POINTER]] takesConstRawPointer(cp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]], UnsafeRawPointer> // CHECK: [[TAKES_CONST_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion20takesConstRawPointeryySVF // CHECK: apply [[TAKES_CONST_RAW_POINTER]] takesConstRawPointer(mrp) // CHECK: [[CONVERT:%.*]] = function_ref @$ss017_convertPointerToB8Argument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]] // CHECK: [[TAKES_CONST_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion20takesConstRawPointeryySVF // CHECK: apply [[TAKES_CONST_RAW_POINTER]] } // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion14arrayToPointeryyF func arrayToPointer() { var ints = [1,2,3] takesMutablePointer(&ints) // CHECK: [[CONVERT_MUTABLE:%.*]] = function_ref @$ss37_convertMutableArrayToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_MUTABLE]]>([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafeMutablePointer on [[OWNER]] // CHECK: [[TAKES_MUTABLE_POINTER:%.*]] = function_ref @$s18pointer_conversion19takesMutablePointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE_POINTER]]([[DEPENDENT]]) // CHECK: destroy_value [[OWNER]] takesConstPointer(ints) // CHECK: [[CONVERT_CONST:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_CONST]]>([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafePointer on [[OWNER]] // CHECK: [[TAKES_CONST_POINTER:%.*]] = function_ref @$s18pointer_conversion17takesConstPointeryySPySiGF // CHECK: apply [[TAKES_CONST_POINTER]]([[DEPENDENT]]) // CHECK: destroy_value [[OWNER]] takesMutableRawPointer(&ints) // CHECK: [[CONVERT_MUTABLE:%.*]] = function_ref @$ss37_convertMutableArrayToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_MUTABLE]]([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafeMutableRawPointer on [[OWNER]] // CHECK: [[TAKES_MUTABLE_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion22takesMutableRawPointeryySvF : // CHECK: apply [[TAKES_MUTABLE_RAW_POINTER]]([[DEPENDENT]]) // CHECK: destroy_value [[OWNER]] takesConstRawPointer(ints) // CHECK: [[CONVERT_CONST:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_CONST]]([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafeRawPointer on [[OWNER]] // CHECK: [[TAKES_CONST_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion20takesConstRawPointeryySVF : // CHECK: apply [[TAKES_CONST_RAW_POINTER]]([[DEPENDENT]]) // CHECK: destroy_value [[OWNER]] takesOptConstPointer(ints, and: sideEffect1()) // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: [[CONVERT_CONST:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_CONST]]>([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafePointer on [[OWNER]] // CHECK: [[OPTPTR:%.*]] = enum $Optional>, #Optional.some!enumelt, [[DEPENDENT]] // CHECK: [[TAKES_OPT_CONST_POINTER:%.*]] = function_ref @$s18pointer_conversion20takesOptConstPointer_3andySPySiGSg_SitF : // CHECK: apply [[TAKES_OPT_CONST_POINTER]]([[OPTPTR]], [[RESULT1]]) // CHECK: destroy_value [[OWNER]] } // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion15stringToPointeryySSF func stringToPointer(_ s: String) { takesConstVoidPointer(s) // CHECK: [[CONVERT_STRING:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_STRING]]([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafeRawPointer on [[OWNER]] // CHECK: [[TAKES_CONST_VOID_POINTER:%.*]] = function_ref @$s18pointer_conversion21takesConstVoidPointeryySV{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_CONST_VOID_POINTER]]([[DEPENDENT]]) // CHECK: destroy_value [[OWNER]] takesConstRawPointer(s) // CHECK: [[CONVERT_STRING:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_STRING]]([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafeRawPointer on [[OWNER]] // CHECK: [[TAKES_CONST_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion20takesConstRawPointeryySV{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_CONST_RAW_POINTER]]([[DEPENDENT]]) // CHECK: destroy_value [[OWNER]] takesOptConstRawPointer(s, and: sideEffect1()) // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: [[CONVERT_STRING:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: [[OWNER:%.*]] = apply [[CONVERT_STRING]]([[POINTER_BUF:%[0-9]*]], // CHECK: [[POINTER:%.*]] = load [trivial] [[POINTER_BUF]] // CHECK: [[DEPENDENT:%.*]] = mark_dependence [[POINTER]] : $UnsafeRawPointer on [[OWNER]] // CHECK: [[OPTPTR:%.*]] = enum $Optional, #Optional.some!enumelt, [[DEPENDENT]] // CHECK: [[TAKES_OPT_CONST_RAW_POINTER:%.*]] = function_ref @$s18pointer_conversion23takesOptConstRawPointer_3andySVSg_SitF : // CHECK: apply [[TAKES_OPT_CONST_RAW_POINTER]]([[OPTPTR]], [[RESULT1]]) // CHECK: destroy_value [[OWNER]] } // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion14inoutToPointeryyF func inoutToPointer() { var int = 0 // CHECK: [[INT:%.*]] = alloc_box ${ var Int } // CHECK: [[PB:%.*]] = project_box [[INT]] takesMutablePointer(&int) // CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] [[PB]] // CHECK: [[POINTER:%.*]] = address_to_pointer [[WRITE]] // CHECK: [[CONVERT:%.*]] = function_ref @$ss30_convertInOutToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]]>({{%.*}}, [[POINTER]]) // CHECK: [[TAKES_MUTABLE:%.*]] = function_ref @$s18pointer_conversion19takesMutablePointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE]] var logicalInt: Int { get { return 0 } set { } } takesMutablePointer(&logicalInt) // CHECK: [[GETTER:%.*]] = function_ref @$s18pointer_conversion14inoutToPointeryyF10logicalIntL_Sivg // CHECK: apply [[GETTER]] // CHECK: [[CONVERT:%.*]] = function_ref @$ss30_convertInOutToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]]> // CHECK: [[TAKES_MUTABLE:%.*]] = function_ref @$s18pointer_conversion19takesMutablePointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE]] // CHECK: [[SETTER:%.*]] = function_ref @$s18pointer_conversion14inoutToPointeryyF10logicalIntL_Sivs // CHECK: apply [[SETTER]] takesMutableRawPointer(&int) // CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] [[PB]] // CHECK: [[POINTER:%.*]] = address_to_pointer [[WRITE]] // CHECK: [[CONVERT:%.*]] = function_ref @$ss30_convertInOutToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]]({{%.*}}, [[POINTER]]) // CHECK: [[TAKES_MUTABLE:%.*]] = function_ref @$s18pointer_conversion22takesMutableRawPointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE]] takesMutableRawPointer(&logicalInt) // CHECK: [[GETTER:%.*]] = function_ref @$s18pointer_conversion14inoutToPointeryyF10logicalIntL_Sivg // CHECK: apply [[GETTER]] // CHECK: [[CONVERT:%.*]] = function_ref @$ss30_convertInOutToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]] // CHECK: [[TAKES_MUTABLE:%.*]] = function_ref @$s18pointer_conversion22takesMutableRawPointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_MUTABLE]] // CHECK: [[SETTER:%.*]] = function_ref @$s18pointer_conversion14inoutToPointeryyF10logicalIntL_Sivs // CHECK: apply [[SETTER]] } class C {} func takesPlusOnePointer(_ x: UnsafeMutablePointer) {} func takesPlusZeroPointer(_ x: AutoreleasingUnsafeMutablePointer) {} func takesPlusZeroOptionalPointer(_ x: AutoreleasingUnsafeMutablePointer) {} // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion19classInoutToPointeryyF func classInoutToPointer() { var c = C() // CHECK: [[VAR:%.*]] = alloc_box ${ var C } // CHECK: [[PB:%.*]] = project_box [[VAR]] takesPlusOnePointer(&c) // CHECK: [[WRITE:%.*]] = begin_access [modify] [unknown] [[PB]] // CHECK: [[POINTER:%.*]] = address_to_pointer [[WRITE]] // CHECK: [[CONVERT:%.*]] = function_ref @$ss30_convertInOutToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]]>({{%.*}}, [[POINTER]]) // CHECK: [[TAKES_PLUS_ONE:%.*]] = function_ref @$s18pointer_conversion19takesPlusOnePointer{{[_0-9a-zA-Z]*}}F // CHECK: apply [[TAKES_PLUS_ONE]] takesPlusZeroPointer(&c) // CHECK: [[WRITEBACK:%.*]] = alloc_stack $@sil_unmanaged C // CHECK: [[OWNED:%.*]] = load_borrow [[PB]] // CHECK: [[UNOWNED:%.*]] = ref_to_unmanaged [[OWNED]] // CHECK: store [[UNOWNED]] to [trivial] [[WRITEBACK]] // CHECK: [[POINTER:%.*]] = address_to_pointer [[WRITEBACK]] // CHECK: [[CONVERT:%.*]] = function_ref @$ss30_convertInOutToPointerArgument{{[_0-9a-zA-Z]*}}F // CHECK: apply [[CONVERT]]>({{%.*}}, [[POINTER]]) // CHECK: [[TAKES_PLUS_ZERO:%.*]] = function_ref @$s18pointer_conversion20takesPlusZeroPointeryySAyAA1CCGF // CHECK: apply [[TAKES_PLUS_ZERO]] // CHECK: [[UNOWNED_OUT:%.*]] = load [trivial] [[WRITEBACK]] // CHECK: [[OWNED_OUT:%.*]] = unmanaged_to_ref [[UNOWNED_OUT]] // CHECK: [[OWNED_OUT_COPY:%.*]] = copy_value [[OWNED_OUT]] // CHECK: assign [[OWNED_OUT_COPY]] to [[PB]] var cq: C? = C() takesPlusZeroOptionalPointer(&cq) } // Check that pointer types don't bridge anymore. @objc class ObjCMethodBridging : NSObject { // CHECK-LABEL: sil hidden [thunk] [ossa] @$s18pointer_conversion18ObjCMethodBridgingC0A4Args{{[_0-9a-zA-Z]*}}FTo : $@convention(objc_method) (UnsafeMutablePointer, UnsafePointer, AutoreleasingUnsafeMutablePointer, ObjCMethodBridging) @objc func pointerArgs(_ x: UnsafeMutablePointer, y: UnsafePointer, z: AutoreleasingUnsafeMutablePointer) {} } // rdar://problem/21505805 // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion22functionInoutToPointeryyF func functionInoutToPointer() { // CHECK: [[BOX:%.*]] = alloc_box ${ var @callee_guaranteed () -> () } var f: () -> () = {} // CHECK: [[REABSTRACT_BUF:%.*]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()> // CHECK: address_to_pointer [[REABSTRACT_BUF]] takesMutableVoidPointer(&f) } // rdar://problem/31781386 // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion20inoutPointerOrderingyyF func inoutPointerOrdering() { // CHECK: [[ARRAY_BOX:%.*]] = alloc_box ${ var Array } // CHECK: [[ARRAY:%.*]] = project_box [[ARRAY_BOX]] : // CHECK: store {{.*}} to [init] [[ARRAY]] var array = [Int]() // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: [[SIDE2:%.*]] = function_ref @$s18pointer_conversion11sideEffect2SiyF // CHECK: [[RESULT2:%.*]] = apply [[SIDE2]]() // CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[ARRAY]] : $*Array // CHECK: [[TAKES_MUTABLE:%.*]] = function_ref @$s18pointer_conversion19takesMutablePointer_3andySpySiG_SitF // CHECK: apply [[TAKES_MUTABLE]]({{.*}}, [[RESULT2]]) // CHECK: end_access [[ACCESS]] takesMutablePointer(&array[sideEffect1()], and: sideEffect2()) // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: [[SIDE2:%.*]] = function_ref @$s18pointer_conversion11sideEffect2SiyF // CHECK: [[RESULT2:%.*]] = apply [[SIDE2]]() // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[ARRAY]] : $*Array // CHECK: [[TAKES_CONST:%.*]] = function_ref @$s18pointer_conversion17takesConstPointer_3andySPySiG_SitF // CHECK: apply [[TAKES_CONST]]({{.*}}, [[RESULT2]]) // CHECK: end_access [[ACCESS]] takesConstPointer(&array[sideEffect1()], and: sideEffect2()) } // rdar://problem/31542269 // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion20optArrayToOptPointer5arrayySaySiGSg_tF func optArrayToOptPointer(array: [Int]?) { // CHECK: [[COPY:%.*]] = copy_value %0 // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: switch_enum [[COPY]] : $Optional>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]] // // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] : // CHECK: [[CONVERT:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgumentyyXlSg_q_tSayxGs01_E0R_r0_lF // CHECK: [[TEMP:%.*]] = alloc_stack $UnsafePointer // CHECK: [[OWNER:%.*]] = apply [[CONVERT]]>([[TEMP:%.*]], [[SOME_VALUE]]) // CHECK: [[PTR:%.*]] = load [trivial] [[TEMP]] // CHECK: [[DEP:%.*]] = mark_dependence [[PTR]] : $UnsafePointer on [[OWNER]] // CHECK: [[OPTPTR:%.*]] = enum $Optional>, #Optional.some!enumelt, [[DEP]] // CHECK: dealloc_stack [[TEMP]] // CHECK: br [[CONT_BB:bb[0-9]+]]([[OPTPTR]] : $Optional>, [[OWNER]] : $Optional) // CHECK: [[CONT_BB]]([[OPTPTR:%.*]] : $Optional>, [[OWNER:%.*]] : @owned $Optional): // CHECK: [[OPTDEP:%.*]] = mark_dependence [[OPTPTR]] : $Optional> on [[OWNER]] // CHECK: [[TAKES:%.*]] = function_ref @$s18pointer_conversion20takesOptConstPointer_3andySPySiGSg_SitF // CHECK: apply [[TAKES]]([[OPTDEP]], [[RESULT1]]) // CHECK: destroy_value [[OWNER]] // CHECK-NOT: destroy_value %0 // CHECK: [[NONE_BB]]: // CHECK: [[NO_VALUE:%.*]] = enum $Optional>, #Optional.none // CHECK: [[NO_OWNER:%.*]] = enum $Optional, #Optional.none // CHECK: br [[CONT_BB]]([[NO_VALUE]] : $Optional>, [[NO_OWNER]] : $Optional) takesOptConstPointer(array, and: sideEffect1()) } // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion013optOptArrayTodD7Pointer5arrayySaySiGSgSg_tF func optOptArrayToOptOptPointer(array: [Int]??) { // CHECK: [[COPY:%.*]] = copy_value %0 // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: switch_enum [[COPY]] : $Optional>>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]] // // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] : // CHECK: switch_enum [[SOME_VALUE]] : $Optional>, case #Optional.some!enumelt: [[SOME_SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[SOME_NONE_BB:bb[0-9]+]] // // CHECK: [[SOME_SOME_BB]]([[SOME_SOME_VALUE:%.*]] : // CHECK: [[CONVERT:%.*]] = function_ref @$ss35_convertConstArrayToPointerArgumentyyXlSg_q_tSayxGs01_E0R_r0_lF // CHECK: [[TEMP:%.*]] = alloc_stack $UnsafePointer // CHECK: [[OWNER:%.*]] = apply [[CONVERT]]>([[TEMP:%.*]], [[SOME_SOME_VALUE]]) // CHECK: [[PTR:%.*]] = load [trivial] [[TEMP]] // CHECK: [[DEP:%.*]] = mark_dependence [[PTR]] : $UnsafePointer on [[OWNER]] // CHECK: [[OPTPTR:%.*]] = enum $Optional>, #Optional.some!enumelt, [[DEP]] // CHECK: dealloc_stack [[TEMP]] // CHECK: br [[SOME_SOME_CONT_BB:bb[0-9]+]]([[OPTPTR]] : $Optional>, [[OWNER]] : $Optional) // CHECK: [[SOME_SOME_CONT_BB]]([[OPTPTR:%.*]] : $Optional>, [[OWNER:%.*]] : @owned $Optional): // CHECK: [[OPTDEP:%.*]] = mark_dependence [[OPTPTR]] : $Optional> on [[OWNER]] // CHECK: [[OPTOPTPTR:%.*]] = enum $Optional>>, #Optional.some!enumelt, [[OPTDEP]] // CHECK: br [[SOME_CONT_BB:bb[0-9]+]]([[OPTOPTPTR]] : $Optional>>, [[OWNER]] : $Optional) // CHECK: [[SOME_CONT_BB]]([[OPTOPTPTR:%.*]] : $Optional>>, [[OWNER:%.*]] : @owned $Optional): // CHECK: [[OPTOPTDEP:%.*]] = mark_dependence [[OPTOPTPTR]] : $Optional>> on [[OWNER]] // CHECK: [[TAKES:%.*]] = function_ref @$s18pointer_conversion08takesOptD12ConstPointer_3andySPySiGSgSg_SitF // CHECK: apply [[TAKES]]([[OPTOPTDEP]], [[RESULT1]]) // CHECK: destroy_value [[OWNER]] // CHECK-NOT: destroy_value %0 // CHECK: [[SOME_NONE_BB]]: // CHECK: [[NO_VALUE:%.*]] = enum $Optional>, #Optional.none // CHECK: [[NO_OWNER:%.*]] = enum $Optional, #Optional.none // CHECK: br [[SOME_SOME_CONT_BB]]([[NO_VALUE]] : $Optional>, [[NO_OWNER]] : $Optional) // CHECK: [[NONE_BB]]: // CHECK: [[NO_VALUE:%.*]] = enum $Optional>>, #Optional.none // CHECK: [[NO_OWNER:%.*]] = enum $Optional, #Optional.none // CHECK: br [[SOME_CONT_BB]]([[NO_VALUE]] : $Optional>>, [[NO_OWNER]] : $Optional) takesOptOptConstPointer(array, and: sideEffect1()) } // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion21optStringToOptPointer6stringySSSg_tF func optStringToOptPointer(string: String?) { // CHECK: [[COPY:%.*]] = copy_value %0 // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // CHECK: switch_enum [[COPY]] : $Optional, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]] // // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] : // CHECK: [[CONVERT:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgumentyyXlSg_xtSSs01_F0RzlF // CHECK: [[TEMP:%.*]] = alloc_stack $UnsafeRawPointer // CHECK: [[OWNER:%.*]] = apply [[CONVERT]]([[TEMP:%.*]], [[SOME_VALUE]]) // CHECK: [[PTR:%.*]] = load [trivial] [[TEMP]] // CHECK: [[DEP:%.*]] = mark_dependence [[PTR]] : $UnsafeRawPointer on [[OWNER]] // CHECK: [[OPTPTR:%.*]] = enum $Optional, #Optional.some!enumelt, [[DEP]] // CHECK: dealloc_stack [[TEMP]] // CHECK: br [[CONT_BB:bb[0-9]+]]([[OPTPTR]] : $Optional, [[OWNER]] : $Optional) // CHECK: [[CONT_BB]]([[OPTPTR:%.*]] : $Optional, [[OWNER:%.*]] : @owned $Optional): // CHECK: [[OPTDEP:%.*]] = mark_dependence [[OPTPTR]] : $Optional on [[OWNER]] // CHECK: [[TAKES:%.*]] = function_ref @$s18pointer_conversion23takesOptConstRawPointer_3andySVSg_SitF // CHECK: apply [[TAKES]]([[OPTDEP]], [[RESULT1]]) // CHECK: destroy_value [[OWNER]] // CHECK-NOT: destroy_value %0 // CHECK: [[NONE_BB]]: // CHECK: [[NO_VALUE:%.*]] = enum $Optional, #Optional.none // CHECK: [[NO_OWNER:%.*]] = enum $Optional, #Optional.none // CHECK: br [[CONT_BB]]([[NO_VALUE]] : $Optional, [[NO_OWNER]] : $Optional) takesOptConstRawPointer(string, and: sideEffect1()) } // CHECK-LABEL: sil hidden [ossa] @$s18pointer_conversion014optOptStringTodD7Pointer6stringySSSgSg_tF func optOptStringToOptOptPointer(string: String??) { // CHECK: [[COPY:%.*]] = copy_value %0 // CHECK: [[SIDE1:%.*]] = function_ref @$s18pointer_conversion11sideEffect1SiyF // CHECK: [[RESULT1:%.*]] = apply [[SIDE1]]() // FIXME: this should really go somewhere that will make nil, not some(nil) // CHECK: switch_enum [[COPY]] : $Optional>, case #Optional.some!enumelt: [[SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]] // // CHECK: [[SOME_BB]]([[SOME_VALUE:%.*]] : // CHECK: switch_enum [[SOME_VALUE]] : $Optional, case #Optional.some!enumelt: [[SOME_SOME_BB:bb[0-9]+]], case #Optional.none!enumelt: [[SOME_NONE_BB:bb[0-9]+]] // CHECK: [[SOME_SOME_BB]]([[SOME_SOME_VALUE:%.*]] : // CHECK: [[CONVERT:%.*]] = function_ref @$ss40_convertConstStringToUTF8PointerArgumentyyXlSg_xtSSs01_F0RzlF // CHECK: [[TEMP:%.*]] = alloc_stack $UnsafeRawPointer // CHECK: [[OWNER:%.*]] = apply [[CONVERT]]([[TEMP:%.*]], [[SOME_SOME_VALUE]]) // CHECK: [[PTR:%.*]] = load [trivial] [[TEMP]] // CHECK: [[DEP:%.*]] = mark_dependence [[PTR]] : $UnsafeRawPointer on [[OWNER]] // CHECK: [[OPTPTR:%.*]] = enum $Optional, #Optional.some!enumelt, [[DEP]] // CHECK: dealloc_stack [[TEMP]] // CHECK: br [[SOME_SOME_CONT_BB:bb[0-9]+]]([[OPTPTR]] : $Optional, [[OWNER]] : $Optional) // CHECK: [[SOME_SOME_CONT_BB]]([[OPTPTR:%.*]] : $Optional, [[OWNER:%.*]] : @owned $Optional): // CHECK: [[OPTDEP:%.*]] = mark_dependence [[OPTPTR]] : $Optional on [[OWNER]] // CHECK: [[OPTOPTPTR:%.*]] = enum $Optional>, #Optional.some!enumelt, [[OPTDEP]] // CHECK: br [[SOME_CONT_BB:bb[0-9]+]]([[OPTOPTPTR]] : $Optional>, [[OWNER]] : $Optional) // CHECK: [[SOME_CONT_BB]]([[OPTOPTPTR:%.*]] : $Optional>, [[OWNER:%.*]] : @owned $Optional): // CHECK: [[OPTOPTDEP:%.*]] = mark_dependence [[OPTOPTPTR]] : $Optional> on [[OWNER]] // CHECK: [[TAKES:%.*]] = function_ref @$s18pointer_conversion08takesOptD15ConstRawPointer_3andySVSgSg_SitF // CHECK: apply [[TAKES]]([[OPTOPTDEP]], [[RESULT1]]) // CHECK: destroy_value [[OWNER]] // CHECK-NOT: destroy_value %0 // CHECK: [[SOME_NONE_BB]]: // CHECK: [[NO_VALUE:%.*]] = enum $Optional, #Optional.none // CHECK: [[NO_OWNER:%.*]] = enum $Optional, #Optional.none // CHECK: br [[SOME_SOME_CONT_BB]]([[NO_VALUE]] : $Optional, [[NO_OWNER]] : $Optional) // CHECK: [[NONE_BB]]: // CHECK: [[NO_VALUE:%.*]] = enum $Optional>, #Optional.none // CHECK: [[NO_OWNER:%.*]] = enum $Optional, #Optional.none // CHECK: br [[SOME_CONT_BB]]([[NO_VALUE]] : $Optional>, [[NO_OWNER]] : $Optional) takesOptOptConstRawPointer(string, and: sideEffect1()) }