Skip to content

Commit a9a477a

Browse files
authored
Merge pull request #12456 from slavapestov/id-as-any-except-when-it-crashes
SILGen: Fix bug with bridging peephole
2 parents d442fb8 + b5cf13d commit a9a477a

File tree

3 files changed

+153
-2
lines changed

3 files changed

+153
-2
lines changed

lib/SILGen/SILGenConvert.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ ManagedValue SILGenFunction::emitExistentialErasure(
695695
assert(existentialTL.isLoadable());
696696

697697
ManagedValue sub = F(SGFContext());
698+
assert(concreteFormalType->isBridgeableObjectType());
698699
return B.createInitExistentialRef(loc, existentialTL.getLoweredType(),
699700
concreteFormalType, sub, conformances);
700701
}
@@ -726,6 +727,7 @@ ManagedValue SILGenFunction::emitExistentialErasure(
726727
auto eraseToAnyObject =
727728
[&, concreteFormalType, F](SGFContext C) -> ManagedValue {
728729
auto concreteValue = F(SGFContext());
730+
assert(concreteFormalType->isBridgeableObjectType());
729731
return B.createInitExistentialRef(
730732
loc, SILType::getPrimitiveObjectType(anyObjectTy), concreteFormalType,
731733
concreteValue, {});
@@ -1231,8 +1233,11 @@ static bool areRelatedTypesForBridgingPeephole(CanType sourceType,
12311233

12321234
// If the result type is AnyObject, then we can always apply the bridge
12331235
// via Any.
1234-
if (resultType->isAnyObject())
1235-
return true;
1236+
if (resultType->isAnyObject()) {
1237+
// ... as long as the source type is not an Optional.
1238+
if (sourceType->isBridgeableObjectType())
1239+
return true;
1240+
}
12361241

12371242
// TODO: maybe other class existentials? Existential conversions?
12381243
// They probably aren't important here.

lib/SILGen/SILGenLValue.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ namespace {
758758
base.getType().getObjectType(),
759759
SGF.getASTContext().AllocateCopy(conformances));
760760
} else {
761+
assert(getSubstFormalType()->isBridgeableObjectType());
761762
ref = SGF.B.createInitExistentialRef(
762763
loc,
763764
base.getType().getObjectType(),

test/SILGen/objc_bridging_peephole.swift

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ func useOptNS(_ : NSString?) {}
1010
func makeNS() -> NSString { return "help" as NSString }
1111
func makeOptNS() -> NSString? { return nil }
1212

13+
func useAnyObject(_: AnyObject) {}
14+
func useOptAnyObject(_: AnyObject?) {}
15+
1316
/*** Return values ***********************************************************/
1417

1518
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole16testMethodResultySo10DummyClassC5dummy_tF
@@ -37,6 +40,35 @@ func testMethodResult(dummy: DummyClass) {
3740
// CHECK-NEXT: apply [[USE]]([[RESULT]])
3841
// CHECK-NEXT: end_borrow [[SELF]] from %0
3942
useOptNS(dummy.fetchNonnullString() as NSString?)
43+
44+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
45+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
46+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
47+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
48+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
49+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
50+
// CHECK-NEXT: end_borrow [[SELF]] from %0
51+
useOptAnyObject(dummy.fetchNullableString() as AnyObject?)
52+
53+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
54+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
55+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
56+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
57+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
58+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
59+
// CHECK-NEXT: end_borrow [[SELF]] from %0
60+
useOptAnyObject(dummy.fetchNullproneString() as AnyObject?)
61+
62+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
63+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
64+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
65+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
66+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
67+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
68+
// CHECK-NEXT: end_borrow [[SELF]] from %0
69+
useOptAnyObject(dummy.fetchNonnullString() as AnyObject?)
70+
71+
// CHECK: return
4072
}
4173

4274
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole23testNonNullMethodResultySo10DummyClassC5dummy_tF
@@ -52,6 +84,21 @@ func testNonNullMethodResult(dummy: DummyClass) {
5284
// CHECK-NEXT: apply [[USE]]([[RESULT]])
5385
// CHECK-NEXT: end_borrow [[SELF]] from %0
5486
useNS(dummy.fetchNonnullString() as NSString)
87+
88+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
89+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
90+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
91+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
92+
// CHECK-NEXT: switch_enum [[RESULT]]
93+
// CHECK: bb3:
94+
// CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
95+
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
96+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
97+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
98+
// CHECK-NEXT: end_borrow [[SELF]] from %0
99+
useAnyObject(dummy.fetchNonnullString() as AnyObject)
100+
101+
// CHECK: return
55102
}
56103

57104
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole22testForcedMethodResultySo10DummyClassC5dummy_tF
@@ -67,6 +114,21 @@ func testForcedMethodResult(dummy: DummyClass) {
67114
// CHECK-NEXT: apply [[USE]]([[RESULT]])
68115
// CHECK-NEXT: end_borrow [[SELF]] from %0
69116
useNS(dummy.fetchNullproneString() as NSString)
117+
118+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
119+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
120+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
121+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
122+
// CHECK-NEXT: switch_enum [[RESULT]]
123+
// CHECK: bb3:
124+
// CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
125+
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
126+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
127+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
128+
// CHECK-NEXT: end_borrow [[SELF]] from %0
129+
useAnyObject(dummy.fetchNullproneString() as AnyObject)
130+
131+
// CHECK: return
70132
}
71133

72134
/*** Property loads **********************************************************/
@@ -96,6 +158,35 @@ func testPropertyValue(dummy: DummyClass) {
96158
// CHECK-NEXT: apply [[USE]]([[RESULT]])
97159
// CHECK-NEXT: end_borrow [[SELF]] from %0
98160
useOptNS(dummy.nonnullStringProperty as NSString?)
161+
162+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
163+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
164+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
165+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
166+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
167+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
168+
// CHECK-NEXT: end_borrow [[SELF]] from %0
169+
useOptAnyObject(dummy.nullableStringProperty as AnyObject?)
170+
171+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
172+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
173+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
174+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
175+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
176+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
177+
// CHECK-NEXT: end_borrow [[SELF]] from %0
178+
useOptAnyObject(dummy.nullproneStringProperty as AnyObject?)
179+
180+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole15useOptAnyObjectyyXlSgF
181+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
182+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
183+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
184+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = unchecked_ref_cast [[RESULT]] : $Optional<NSString> to $Optional<AnyObject>
185+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
186+
// CHECK-NEXT: end_borrow [[SELF]] from %0
187+
useOptAnyObject(dummy.nonnullStringProperty as AnyObject?)
188+
189+
// CHECK: return
99190
}
100191

101192
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole24testNonNullPropertyValueySo10DummyClassC5dummy_tF
@@ -111,6 +202,21 @@ func testNonNullPropertyValue(dummy: DummyClass) {
111202
// CHECK-NEXT: apply [[USE]]([[RESULT]])
112203
// CHECK-NEXT: end_borrow [[SELF]] from %0
113204
useNS(dummy.nonnullStringProperty as NSString)
205+
206+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
207+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
208+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
209+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
210+
// CHECK-NEXT: switch_enum [[RESULT]]
211+
// CHECK: bb3:
212+
// CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
213+
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
214+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
215+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
216+
// CHECK-NEXT: end_borrow [[SELF]] from %0
217+
useAnyObject(dummy.nonnullStringProperty as AnyObject)
218+
219+
// CHECK: return
114220
}
115221

116222
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole23testForcedPropertyValueySo10DummyClassC5dummy_tF
@@ -126,6 +232,21 @@ func testForcedPropertyValue(dummy: DummyClass) {
126232
// CHECK-NEXT: apply [[USE]]([[RESULT]])
127233
// CHECK-NEXT: end_borrow [[SELF]] from %0
128234
useNS(dummy.nullproneStringProperty as NSString)
235+
236+
// CHECK: [[USE:%.*]] = function_ref @_T022objc_bridging_peephole12useAnyObjectyyXlF
237+
// CHECK-NEXT: [[SELF:%.*]] = begin_borrow %0
238+
// CHECK-NEXT: [[METHOD:%.*]] = objc_method
239+
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
240+
// CHECK-NEXT: switch_enum [[RESULT]]
241+
// CHECK: bb3:
242+
// CHECK: function_ref @_T0s30_diagnoseUnexpectedNilOptionalyBp14_filenameStart_Bw01_E6LengthBi1_01_E7IsASCIIBw5_linetF
243+
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
244+
// CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
245+
// CHECK-NEXT: apply [[USE]]([[ANYOBJECT]])
246+
// CHECK-NEXT: end_borrow [[SELF]] from %0
247+
useAnyObject(dummy.nullproneStringProperty as AnyObject)
248+
249+
// CHECK: return
129250
}
130251

131252
/*** Subscript loads *********************************************************/
@@ -158,6 +279,8 @@ func testNonnullSubscriptGet(object: NonnullSubscript, index: AnyObject) {
158279
// CHECK-NEXT: apply [[USE]]([[RESULT]])
159280
// CHECK: end_borrow [[SELF]] from %0
160281
useNS(object[index] as NSString)
282+
283+
// CHECK: return
161284
}
162285

163286
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole24testNullableSubscriptGetySo0eF0C6object_yXl5indextF
@@ -172,6 +295,8 @@ func testNullableSubscriptGet(object: NullableSubscript, index: AnyObject) {
172295
// CHECK-NEXT: apply [[USE]]([[RESULT]])
173296
// CHECK: end_borrow [[SELF]] from %0
174297
useOptNS(object[index] as NSString?)
298+
299+
// CHECK: return
175300
}
176301

177302
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole25testNullproneSubscriptGetySo0eF0C6object_yXl5indextF
@@ -200,6 +325,8 @@ func testNullproneSubscriptGet(object: NullproneSubscript, index: AnyObject) {
200325
// CHECK-NEXT: apply [[USE]]([[RESULT]])
201326
// CHECK: end_borrow [[SELF]] from %0
202327
useNS(object[index] as NSString)
328+
329+
// CHECK: return
203330
}
204331

205332
/*** Call arguments **********************************************************/
@@ -237,6 +364,8 @@ func testMethodArgument(dummy: DummyClass) {
237364
// CHECK-NEXT: destroy_value [[OPTARG]]
238365
// CHECK-NEXT: end_borrow [[SELF]] from %0
239366
dummy.takeNullproneString(makeNS() as String)
367+
368+
// CHECK: return
240369
}
241370

242371
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole28testValueToOptMethodArgumentySo10DummyClassC5dummy_tF
@@ -262,6 +391,8 @@ func testValueToOptMethodArgument(dummy: DummyClass) {
262391
// CHECK-NEXT: destroy_value [[OPTARG]]
263392
// CHECK-NEXT: end_borrow [[SELF]] from %0
264393
dummy.takeNullproneString(makeNS() as String?)
394+
395+
// CHECK: return
265396
}
266397

267398
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole09testOptToE14MethodArgumentySo10DummyClassC5dummy_tF
@@ -285,6 +416,8 @@ func testOptToOptMethodArgument(dummy: DummyClass) {
285416
// CHECK-NEXT: destroy_value [[ARG]]
286417
// CHECK-NEXT: end_borrow [[SELF]] from %0
287418
dummy.takeNullproneString(makeOptNS() as String?)
419+
420+
// CHECK: return
288421
}
289422

290423
/*** Property assignments ****************************************************/
@@ -322,6 +455,8 @@ func testPropertySetter(dummy: DummyClass) {
322455
// CHECK-NEXT: destroy_value [[OPTARG]]
323456
// CHECK-NEXT: end_borrow [[SELF]] from %0
324457
dummy.nullproneStringProperty = makeNS() as String
458+
459+
// CHECK: return
325460
}
326461

327462
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole28testValueToOptPropertySetterySo10DummyClassC5dummy_tF
@@ -347,6 +482,8 @@ func testValueToOptPropertySetter(dummy: DummyClass) {
347482
// CHECK-NEXT: destroy_value [[OPTARG]]
348483
// CHECK-NEXT: end_borrow [[SELF]] from %0
349484
dummy.nullproneStringProperty = makeNS() as String?
485+
486+
// CHECK: return
350487
}
351488

352489
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole09testOptToE14PropertySetterySo10DummyClassC5dummy_tF
@@ -370,6 +507,8 @@ func testOptToOptPropertySetter(dummy: DummyClass) {
370507
// CHECK-NEXT: destroy_value [[ARG]]
371508
// CHECK-NEXT: end_borrow [[SELF]] from %0
372509
dummy.nullproneStringProperty = makeOptNS() as String?
510+
511+
// CHECK: return
373512
}
374513

375514
/*** Subscript assignments ***************************************************/
@@ -389,6 +528,8 @@ func testNonnullSubscriptSet(object: NonnullSubscript, index: AnyObject) {
389528
// CHECK: destroy_value [[ARG]]
390529
// CHECK: end_borrow [[SELF]] from %0
391530
object[index] = makeNS() as String
531+
532+
// CHECK: return
392533
}
393534

394535
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole24testNullableSubscriptSetySo0eF0C6object_yXl5indextF
@@ -430,6 +571,8 @@ func testNullableSubscriptSet(object: NullableSubscript, index: AnyObject) {
430571
// CHECK: destroy_value [[ARG]]
431572
// CHECK: end_borrow [[SELF]] from %0
432573
object[index] = makeOptNS() as String?
574+
575+
// CHECK: return
433576
}
434577

435578
// CHECK-LABEL: sil hidden @_T022objc_bridging_peephole25testNullproneSubscriptSetySo0eF0C6object_yXl5indextF
@@ -471,6 +614,8 @@ func testNullproneSubscriptSet(object: NullproneSubscript, index: AnyObject) {
471614
// CHECK: destroy_value [[ARG]]
472615
// CHECK: end_borrow [[SELF]] from %0
473616
object[index] = makeOptNS() as String?
617+
618+
// CHECK: return
474619
}
475620

476621
/*** Bugfixes ***************************************************************/

0 commit comments

Comments
 (0)