mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Now that - owned arguments don't get lexical borrow scopes from SILGen - owned arguments get lexical moves during inlining unless the value passed for that argument is already lexical - guaranteed arguments don't get lexical borrow scopes during inlining when the value passed for that argument is already lexical tests involving owned argument emission from SILGen and inlining need to be updated.
594 lines
30 KiB
Swift
594 lines
30 KiB
Swift
|
|
// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) -module-name objc_bridging_peephole %s | %FileCheck %s
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
import OtherSubscripts
|
|
import objc_generics
|
|
|
|
func useNS(_ : NSString) {}
|
|
func useOptNS(_ : NSString?) {}
|
|
func makeNS() -> NSString { return "help" as NSString }
|
|
func makeOptNS() -> NSString? { return nil }
|
|
|
|
func useAnyObject(_: AnyObject) {}
|
|
func useOptAnyObject(_: AnyObject?) {}
|
|
|
|
/*** Return values ***********************************************************/
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole16testMethodResult5dummyySo10DummyClassC_tF
|
|
func testMethodResult(dummy: DummyClass) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $DummyClass, #DummyClass.fetchNullableString!foreign
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useOptNS(dummy.fetchNullableString() as NSString?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $DummyClass, #DummyClass.fetchNullproneString!foreign
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useOptNS(dummy.fetchNullproneString() as NSString?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method [[SELF]] : $DummyClass, #DummyClass.fetchNonnullString!foreign
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useOptNS(dummy.fetchNonnullString() as NSString?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole15useOptAnyObjectyyyXlSgF
|
|
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
|
|
useOptAnyObject(dummy.fetchNullableString() as AnyObject?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole15useOptAnyObjectyyyXlSgF
|
|
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
|
|
useOptAnyObject(dummy.fetchNullproneString() as AnyObject?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole15useOptAnyObjectyyyXlSgF
|
|
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
|
|
useOptAnyObject(dummy.fetchNonnullString() as AnyObject?)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole23testNonNullMethodResult5dummyySo10DummyClassC_tF
|
|
func testNonNullMethodResult(dummy: DummyClass) {
|
|
// CHECK: bb0([[ARG:%.*]] @guaranteed $DummyClass):
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: switch_enum [[RESULT]]
|
|
//
|
|
// CHECK: bb1:
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole5useNSyySo8NSStringCF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useNS(dummy.fetchNonnullString() as NSString)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: switch_enum [[RESULT]]
|
|
// CHECK: bb3:
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole12useAnyObjectyyyXlF
|
|
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
|
|
useAnyObject(dummy.fetchNonnullString() as AnyObject)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole22testForcedMethodResult5dummyySo10DummyClassC_tF
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $DummyClass):
|
|
func testForcedMethodResult(dummy: DummyClass) {
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: switch_enum [[RESULT]]
|
|
// CHECK: bb1:
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole5useNSyySo8NSStringCF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useNS(dummy.fetchNullproneString() as NSString)
|
|
|
|
// This is not a force.
|
|
// TODO: we could do it more efficiently than this, though
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK-NEXT: switch_enum [[RESULT]]
|
|
//
|
|
// CHECK: bb3([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: function_ref @$sSS10FoundationE36_unconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ
|
|
//
|
|
// CHECK: bb4:
|
|
// CHECK: enum $Optional<String>, #Optional.none
|
|
//
|
|
// CHECK: bb5([[OPTSTRING:%.*]] : @owned $Optional<String>):
|
|
// CHECK: [[BRIDGE:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Optional<String>
|
|
// CHECK-NEXT: [[BORROW:%.*]] = begin_borrow [[OPTSTRING]]
|
|
// CHECK-NEXT: [[SB:%.*]] = store_borrow [[BORROW]] to [[TEMP]] : $*Optional<String>
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = apply [[BRIDGE]]<String>([[SB]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole12useAnyObjectyyyXlF
|
|
// CHECK: apply [[USE]]([[ANYOBJECT]])
|
|
useAnyObject(dummy.fetchNullproneString() as AnyObject)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
/*** Property loads **********************************************************/
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole17testPropertyValue5dummyySo10DummyClassC_tF
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $DummyClass):
|
|
func testPropertyValue(dummy: DummyClass) {
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK: apply [[USE]]([[RESULT]])
|
|
useOptNS(dummy.nullableStringProperty as NSString?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK: apply [[USE]]([[RESULT]])
|
|
useOptNS(dummy.nullproneStringProperty as NSString?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK: apply [[USE]]([[RESULT]])
|
|
useOptNS(dummy.nonnullStringProperty as NSString?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole15useOptAnyObjectyyyXlSgF
|
|
// CHECK: apply [[USE]]([[ANYOBJECT]])
|
|
useOptAnyObject(dummy.nullableStringProperty as AnyObject?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole15useOptAnyObjectyyyXlSgF
|
|
// CHECK: apply [[USE]]([[ANYOBJECT]])
|
|
useOptAnyObject(dummy.nullproneStringProperty as AnyObject?)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole15useOptAnyObjectyyyXlSgF
|
|
// CHECK: apply [[USE]]([[ANYOBJECT]])
|
|
useOptAnyObject(dummy.nonnullStringProperty as AnyObject?)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole24testNonNullPropertyValue5dummyySo10DummyClassC_tF
|
|
func testNonNullPropertyValue(dummy: DummyClass) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: switch_enum [[RESULT]]
|
|
// CHECK: bb1:
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole5useNSyySo8NSStringCF
|
|
// CHECK: apply [[USE]]([[RESULT]])
|
|
useNS(dummy.nonnullStringProperty as NSString)
|
|
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: switch_enum [[RESULT]]
|
|
// CHECK: bb3:
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole12useAnyObjectyyyXlF
|
|
// CHECK: apply [[USE]]([[ANYOBJECT]])
|
|
useAnyObject(dummy.nonnullStringProperty as AnyObject)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole23testForcedPropertyValue5dummyySo10DummyClassC_tF
|
|
func testForcedPropertyValue(dummy: DummyClass) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: switch_enum [[RESULT]]
|
|
// CHECK: bb1:
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole5useNSyySo8NSStringCF
|
|
// CHECK: apply [[USE]]([[RESULT]])
|
|
useNS(dummy.nullproneStringProperty as NSString)
|
|
|
|
// This is not a force.
|
|
// TODO: we could do it more efficiently than this, though
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
|
|
// CHECK: switch_enum [[RESULT]]
|
|
// CHECK: bb3([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: function_ref @$sSS10FoundationE36_unconditionallyBridgeFromObjectiveCySSSo8NSStringCSgFZ
|
|
// CHECK: bb4:
|
|
// CHECK: enum $Optional<String>, #Optional.none
|
|
// CHECK: bb5([[OPTSTRING:%.*]] : @owned $Optional<String>):
|
|
// CHECK: [[BRIDGE:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $Optional<String>
|
|
// CHECK-NEXT: [[BORROW:%.*]] = begin_borrow [[OPTSTRING]]
|
|
// CHECK-NEXT: [[SB:%.*]] = store_borrow [[BORROW]] to [[TEMP]] : $*Optional<String>
|
|
// CHECK-NEXT: [[ANYOBJECT:%.*]] = apply [[BRIDGE]]<String>([[SB]])
|
|
// CHECK: dealloc_stack [[TEMP]]
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole12useAnyObjectyyyXlF
|
|
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
|
|
// CHECK: destroy_value [[OPTSTRING]]
|
|
useAnyObject(dummy.nullproneStringProperty as AnyObject)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
/*** Subscript loads *********************************************************/
|
|
|
|
// FIXME: apply peepholes to indices, too!
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole23testNonnullSubscriptGet6object5indexySo0eF0C_yXltF
|
|
func testNonnullSubscriptGet(object: NonnullSubscript, index: AnyObject) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $NonnullSubscript,
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useOptNS(object[index] as NSString?)
|
|
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
|
|
// CHECK-NEXT: switch_enum [[RESULT]]
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb{{[0-9]+}}([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole5useNSyySo8NSStringCF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useNS(object[index] as NSString)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole24testNullableSubscriptGet6object5indexySo0eF0C_yXltF
|
|
func testNullableSubscriptGet(object: NullableSubscript, index: AnyObject) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $NullableSubscript,
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useOptNS(object[index] as NSString?)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole25testNullproneSubscriptGet6object5indexySo0eF0C_yXltF
|
|
func testNullproneSubscriptGet(object: NullproneSubscript, index: AnyObject) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $NullproneSubscript,
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole8useOptNSyySo8NSStringCSgF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useOptNS(object[index] as NSString?)
|
|
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
|
|
// CHECK-NEXT: switch_enum [[RESULT]]
|
|
// CHECK: function_ref @$ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
|
|
// CHECK: bb{{[0-9]+}}([[RESULT:%.*]] : @owned $NSString):
|
|
// CHECK: [[USE:%.*]] = function_ref @$s22objc_bridging_peephole5useNSyySo8NSStringCF
|
|
// CHECK-NEXT: apply [[USE]]([[RESULT]])
|
|
useNS(object[index] as NSString)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
/*** Call arguments **********************************************************/
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole18testMethodArgument5dummyySo10DummyClassC_tF
|
|
func testMethodArgument(dummy: DummyClass) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: // function_ref
|
|
// CHECK-NEXT: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[ARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[ARG]]
|
|
dummy.takeNonnullString(makeNS() as String)
|
|
|
|
// CHECK: // function_ref
|
|
// CHECK-NEXT: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.takeNullableString(makeNS() as String)
|
|
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.takeNullproneString(makeNS() as String)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole28testValueToOptMethodArgument5dummyySo10DummyClassC_tF
|
|
func testValueToOptMethodArgument(dummy: DummyClass) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.takeNullableString(makeNS() as String?)
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.takeNullproneString(makeNS() as String?)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole09testOptToE14MethodArgument5dummyySo10DummyClassC_tF
|
|
func testOptToOptMethodArgument(dummy: DummyClass) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole9makeOptNSSo8NSStringCSgyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[ARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[ARG]]
|
|
dummy.takeNullableString(makeOptNS() as String?)
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole9makeOptNSSo8NSStringCSgyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[ARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[ARG]]
|
|
dummy.takeNullproneString(makeOptNS() as String?)
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
/*** Property assignments ****************************************************/
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole18testPropertySetter5dummyySo10DummyClassC_tF
|
|
func testPropertySetter(dummy: DummyClass) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[ARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[ARG]]
|
|
dummy.nonnullStringProperty = makeNS() as String
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.nullableStringProperty = makeNS() as String
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.nullproneStringProperty = makeNS() as String
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole28testValueToOptPropertySetter5dummyySo10DummyClassC_tF
|
|
func testValueToOptPropertySetter(dummy: DummyClass) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.nullableStringProperty = makeNS() as String?
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]] : $NSString
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[OPTARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[OPTARG]]
|
|
dummy.nullproneStringProperty = makeNS() as String?
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole09testOptToE14PropertySetter5dummyySo10DummyClassC_tF
|
|
func testOptToOptPropertySetter(dummy: DummyClass) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $DummyClass):
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole9makeOptNSSo8NSStringCSgyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[ARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[ARG]]
|
|
dummy.nullableStringProperty = makeOptNS() as String?
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole9makeOptNSSo8NSStringCSgyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
|
|
// CHECK-NEXT: apply [[METHOD]]([[ARG]], [[SELF]])
|
|
// CHECK-NEXT: destroy_value [[ARG]]
|
|
dummy.nullproneStringProperty = makeOptNS() as String?
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
/*** Subscript assignments ***************************************************/
|
|
|
|
// FIXME: apply peepholes to indices, too!
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole23testNonnullSubscriptSet6object5indexySo0eF0C_yXltF
|
|
func testNonnullSubscriptSet(object: NonnullSubscript, index: AnyObject) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $NonnullSubscript,
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[ARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[ARG]]
|
|
object[index] = makeNS() as String
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole24testNullableSubscriptSet6object5indexySo0eF0C_yXltF
|
|
func testNullableSubscriptSet(object: NullableSubscript, index: AnyObject) {
|
|
// CHECK: bb0([[SELF:%.*]] : @guaranteed $NullableSubscript,
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]]
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[OPTARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[OPTARG]]
|
|
object[index] = makeNS() as String
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]]
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[OPTARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[OPTARG]]
|
|
object[index] = makeNS() as String?
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole9makeOptNSSo8NSStringCSgyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[ARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[ARG]]
|
|
object[index] = makeOptNS() as String?
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole25testNullproneSubscriptSet6object5indexySo0eF0C_yXltF
|
|
func testNullproneSubscriptSet(object: NullproneSubscript, index: AnyObject) {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $NullproneSubscript,
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]]
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[OPTARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[OPTARG]]
|
|
object[index] = makeNS() as String
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole6makeNSSo8NSStringCyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK-NEXT: [[OPTARG:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt, [[ARG]]
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[OPTARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[OPTARG]]
|
|
object[index] = makeNS() as String?
|
|
|
|
// CHECK: [[MAKE:%.*]] = function_ref @$s22objc_bridging_peephole9makeOptNSSo8NSStringCSgyF
|
|
// CHECK-NEXT: [[ARG:%.*]] = apply [[MAKE]]()
|
|
// CHECK: [[BRIDGE_TO_ID:%.*]] = function_ref @$ss27_bridgeAnythingToObjectiveCyyXlxlF
|
|
// CHECK-NEXT: [[INDEX:%.*]] = apply [[BRIDGE_TO_ID]]
|
|
// CHECK: [[METHOD:%.*]] = objc_method
|
|
// CHECK: apply [[METHOD]]([[ARG]], [[INDEX]], [[SELF]])
|
|
// CHECK: destroy_value [[INDEX]]
|
|
// CHECK: destroy_value [[ARG]]
|
|
object[index] = makeOptNS() as String?
|
|
|
|
// CHECK: return
|
|
}
|
|
|
|
/*** Bugfixes ***************************************************************/
|
|
|
|
protocol P {
|
|
var title : String { get }
|
|
}
|
|
|
|
func foo(p: P) {
|
|
DummyClass().takeNullableString(p.title)
|
|
}
|
|
|
|
// rdar://35402853
|
|
// Make sure that we don't peephole AnyObject? -> Any? -> AnyObject naively.
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole017testOptionalToNonE6BridgeyyF
|
|
func testOptionalToNonOptionalBridge() {
|
|
// CHECK: apply {{.*}}() : $@convention(c) () -> @autoreleased Optional<AnyObject>
|
|
// CHECK: function_ref @$ss018_bridgeAnyObjectToB0yypyXlSgF :
|
|
// CHECK: [[T0:%.*]] = function_ref @$sSq19_bridgeToObjectiveCyXlyF
|
|
// CHECK: apply [[T0]]<Any>
|
|
useAnyObject(returnNullableId() as AnyObject)
|
|
} // CHECK: end sil function '$s22objc_bridging_peephole017testOptionalToNonE6BridgeyyF'
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s22objc_bridging_peephole34testBlockToOptionalAnyObjectBridge5blockyyyXB_tF
|
|
func testBlockToOptionalAnyObjectBridge(block: @escaping @convention(block) () -> ()) {
|
|
// CHECK: debug_value
|
|
// CHECK-NEXT: [[T0:%.*]] = begin_borrow {{%.*}} : $@convention(block) () -> ()
|
|
// CHECK-NEXT: [[T1:%.*]] = copy_value [[T0]]
|
|
// CHECK-NEXT: [[REF:%.*]] = unchecked_ref_cast [[T1]] : $@convention(block) () -> () to $AnyObject
|
|
// CHECK-NEXT: [[OPTREF:%.*]] = enum $Optional<AnyObject>, #Optional.some!enumelt, [[REF]] : $AnyObject
|
|
// CHECK-NEXT: end_borrow [[T0]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[FN:%.*]] = function_ref @takeNullableId : $@convention(c) (Optional<AnyObject>) -> ()
|
|
// CHECK-NEXT: apply [[FN]]([[OPTREF]])
|
|
// CHECK-NEXT: destroy_value [[OPTREF]]
|
|
takeNullableId(block as Any)
|
|
}
|