Merge pull request #12456 from slavapestov/id-as-any-except-when-it-crashes
SILGen: Fix bug with bridging peephole
diff --git a/lib/SILGen/SILGenConvert.cpp b/lib/SILGen/SILGenConvert.cpp
index 38d9033..4009cc0 100644
--- a/lib/SILGen/SILGenConvert.cpp
+++ b/lib/SILGen/SILGenConvert.cpp
@@ -695,6 +695,7 @@
assert(existentialTL.isLoadable());
ManagedValue sub = F(SGFContext());
+ assert(concreteFormalType->isBridgeableObjectType());
return B.createInitExistentialRef(loc, existentialTL.getLoweredType(),
concreteFormalType, sub, conformances);
}
@@ -726,6 +727,7 @@
auto eraseToAnyObject =
[&, concreteFormalType, F](SGFContext C) -> ManagedValue {
auto concreteValue = F(SGFContext());
+ assert(concreteFormalType->isBridgeableObjectType());
return B.createInitExistentialRef(
loc, SILType::getPrimitiveObjectType(anyObjectTy), concreteFormalType,
concreteValue, {});
@@ -1231,8 +1233,11 @@
// If the result type is AnyObject, then we can always apply the bridge
// via Any.
- if (resultType->isAnyObject())
- return true;
+ if (resultType->isAnyObject()) {
+ // ... as long as the source type is not an Optional.
+ if (sourceType->isBridgeableObjectType())
+ return true;
+ }
// TODO: maybe other class existentials? Existential conversions?
// They probably aren't important here.
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 8d65a2d..8b19cf9 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -758,6 +758,7 @@
base.getType().getObjectType(),
SGF.getASTContext().AllocateCopy(conformances));
} else {
+ assert(getSubstFormalType()->isBridgeableObjectType());
ref = SGF.B.createInitExistentialRef(
loc,
base.getType().getObjectType(),
diff --git a/test/SILGen/objc_bridging_peephole.swift b/test/SILGen/objc_bridging_peephole.swift
index 6c25326..6697bd3 100644
--- a/test/SILGen/objc_bridging_peephole.swift
+++ b/test/SILGen/objc_bridging_peephole.swift
@@ -10,6 +10,9 @@
func makeNS() -> NSString { return "help" as NSString }
func makeOptNS() -> NSString? { return nil }
+func useAnyObject(_: AnyObject) {}
+func useOptAnyObject(_: AnyObject?) {}
+
/*** Return values ***********************************************************/
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole16testMethodResultySo10DummyClassC5dummy_tF
@@ -37,6 +40,35 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK-NEXT: end_borrow [[SELF]] from %0
useOptNS(dummy.fetchNonnullString() as NSString?)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useOptAnyObject(dummy.fetchNullableString() as AnyObject?)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useOptAnyObject(dummy.fetchNullproneString() as AnyObject?)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useOptAnyObject(dummy.fetchNonnullString() as AnyObject?)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole23testNonNullMethodResultySo10DummyClassC5dummy_tF
@@ -52,6 +84,21 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK-NEXT: end_borrow [[SELF]] from %0
useNS(dummy.fetchNonnullString() as NSString)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: switch_enum [[RESULT]]
+ // CHECK: bb3:
+ // CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
+ // CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useAnyObject(dummy.fetchNonnullString() as AnyObject)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole22testForcedMethodResultySo10DummyClassC5dummy_tF
@@ -67,6 +114,21 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK-NEXT: end_borrow [[SELF]] from %0
useNS(dummy.fetchNullproneString() as NSString)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: switch_enum [[RESULT]]
+ // CHECK: bb3:
+ // CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
+ // CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useAnyObject(dummy.fetchNullproneString() as AnyObject)
+
+ // CHECK: return
}
/*** Property loads **********************************************************/
@@ -96,6 +158,35 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK-NEXT: end_borrow [[SELF]] from %0
useOptNS(dummy.nonnullStringProperty as NSString?)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useOptAnyObject(dummy.nullableStringProperty as AnyObject?)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useOptAnyObject(dummy.nullproneStringProperty as AnyObject?)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useOptAnyObject(dummy.nonnullStringProperty as AnyObject?)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole24testNonNullPropertyValueySo10DummyClassC5dummy_tF
@@ -111,6 +202,21 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK-NEXT: end_borrow [[SELF]] from %0
useNS(dummy.nonnullStringProperty as NSString)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: switch_enum [[RESULT]]
+ // CHECK: bb3:
+ // CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
+ // CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useAnyObject(dummy.nonnullStringProperty as AnyObject)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole23testForcedPropertyValueySo10DummyClassC5dummy_tF
@@ -126,6 +232,21 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK-NEXT: end_borrow [[SELF]] from %0
useNS(dummy.nullproneStringProperty as NSString)
+
+ // CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
+ // CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
+ // CHECK-NEXT: [[METHOD:%.*]] = objc_method
+ // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
+ // CHECK-NEXT: switch_enum [[RESULT]]
+ // CHECK: bb3:
+ // CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
+ // CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
+ // CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
+ // CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
+ // CHECK-NEXT: end_borrow [[SELF]] from %0
+ useAnyObject(dummy.nullproneStringProperty as AnyObject)
+
+ // CHECK: return
}
/*** Subscript loads *********************************************************/
@@ -158,6 +279,8 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK: end_borrow [[SELF]] from %0
useNS(object[index] as NSString)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole24testNullableSubscriptGetySo0eF0C6object_yXl5indextF
@@ -172,6 +295,8 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK: end_borrow [[SELF]] from %0
useOptNS(object[index] as NSString?)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole25testNullproneSubscriptGetySo0eF0C6object_yXl5indextF
@@ -200,6 +325,8 @@
// CHECK-NEXT: apply [[USE]]([[RESULT]])
// CHECK: end_borrow [[SELF]] from %0
useNS(object[index] as NSString)
+
+ // CHECK: return
}
/*** Call arguments **********************************************************/
@@ -237,6 +364,8 @@
// CHECK-NEXT: destroy_value [[OPTARG]]
// CHECK-NEXT: end_borrow [[SELF]] from %0
dummy.takeNullproneString(makeNS() as String)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole28testValueToOptMethodArgumentySo10DummyClassC5dummy_tF
@@ -262,6 +391,8 @@
// CHECK-NEXT: destroy_value [[OPTARG]]
// CHECK-NEXT: end_borrow [[SELF]] from %0
dummy.takeNullproneString(makeNS() as String?)
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole09testOptToE14MethodArgumentySo10DummyClassC5dummy_tF
@@ -285,6 +416,8 @@
// CHECK-NEXT: destroy_value [[ARG]]
// CHECK-NEXT: end_borrow [[SELF]] from %0
dummy.takeNullproneString(makeOptNS() as String?)
+
+ // CHECK: return
}
/*** Property assignments ****************************************************/
@@ -322,6 +455,8 @@
// CHECK-NEXT: destroy_value [[OPTARG]]
// CHECK-NEXT: end_borrow [[SELF]] from %0
dummy.nullproneStringProperty = makeNS() as String
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole28testValueToOptPropertySetterySo10DummyClassC5dummy_tF
@@ -347,6 +482,8 @@
// CHECK-NEXT: destroy_value [[OPTARG]]
// CHECK-NEXT: end_borrow [[SELF]] from %0
dummy.nullproneStringProperty = makeNS() as String?
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole09testOptToE14PropertySetterySo10DummyClassC5dummy_tF
@@ -370,6 +507,8 @@
// CHECK-NEXT: destroy_value [[ARG]]
// CHECK-NEXT: end_borrow [[SELF]] from %0
dummy.nullproneStringProperty = makeOptNS() as String?
+
+ // CHECK: return
}
/*** Subscript assignments ***************************************************/
@@ -389,6 +528,8 @@
// CHECK: destroy_value [[ARG]]
// CHECK: end_borrow [[SELF]] from %0
object[index] = makeNS() as String
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole24testNullableSubscriptSetySo0eF0C6object_yXl5indextF
@@ -430,6 +571,8 @@
// CHECK: destroy_value [[ARG]]
// CHECK: end_borrow [[SELF]] from %0
object[index] = makeOptNS() as String?
+
+ // CHECK: return
}
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole25testNullproneSubscriptSetySo0eF0C6object_yXl5indextF
@@ -471,6 +614,8 @@
// CHECK: destroy_value [[ARG]]
// CHECK: end_borrow [[SELF]] from %0
object[index] = makeOptNS() as String?
+
+ // CHECK: return
}
/*** Bugfixes ***************************************************************/