Skip to content

Commit b6e3503

Browse files
committed
[SILGen] Output a different message for failed IUO force-unwraps
Modifies SILGen and the `Swift._diagnoseUnexpectedNilOptional` call to print a slightly different message for force unwraps which were implicitly inserted by the compiler for IUOs. The message is chosen based on the presence of certain flags in the `ForceValueExpr`, not on the type of the value being unwrapped.
1 parent 520c645 commit b6e3503

File tree

12 files changed

+178
-36
lines changed

12 files changed

+178
-36
lines changed

lib/SILGen/Conversion.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class Conversion {
3333
BridgeToObjC,
3434

3535
/// A bridging conversion to a foreign type following a force.
36+
/// Although it's not reflected in the name, this is always an
37+
/// implicit force cast.
3638
ForceAndBridgeToObjC,
3739

3840
/// A bridging conversion from a foreign type.

lib/SILGen/SILGenConvert.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ auto SILGenFunction::emitSourceLocationArgs(SourceLoc sourceLoc,
182182

183183
ManagedValue
184184
SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc,
185-
ManagedValue optional) {
185+
ManagedValue optional,
186+
bool isImplicitUnwrap) {
186187
// Generate code to the optional is present, and if not, abort with a message
187188
// (provided by the stdlib).
188189
SILBasicBlock *contBB = createBasicBlock();
@@ -217,12 +218,19 @@ SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc,
217218
getASTContext().getDiagnoseUnexpectedNilOptional(nullptr)) {
218219
auto args = emitSourceLocationArgs(loc.getSourceLoc(), loc);
219220

221+
auto i1Ty = SILType::getBuiltinIntegerType(1, getASTContext());
222+
auto isImplicitUnwrapLiteral =
223+
B.createIntegerLiteral(loc, i1Ty, isImplicitUnwrap);
224+
auto isImplicitUnwrapValue =
225+
ManagedValue::forUnmanaged(isImplicitUnwrapLiteral);
226+
220227
emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, SubstitutionMap(),
221228
{
222229
args.filenameStartPointer,
223230
args.filenameLength,
224231
args.filenameIsAscii,
225-
args.line
232+
args.line,
233+
isImplicitUnwrapValue
226234
},
227235
SGFContext());
228236
}
@@ -268,10 +276,11 @@ SILValue SILGenFunction::emitDoesOptionalHaveValue(SILLocation loc,
268276

269277
ManagedValue SILGenFunction::emitCheckedGetOptionalValueFrom(SILLocation loc,
270278
ManagedValue src,
279+
bool isImplicitUnwrap,
271280
const TypeLowering &optTL,
272281
SGFContext C) {
273282
// TODO: Make this take optTL.
274-
return emitPreconditionOptionalHasValue(loc, src);
283+
return emitPreconditionOptionalHasValue(loc, src, isImplicitUnwrap);
275284
}
276285

277286
ManagedValue SILGenFunction::emitUncheckedGetOptionalValueFrom(
@@ -1103,7 +1112,9 @@ ManagedValue Conversion::emit(SILGenFunction &SGF, SILLocation loc,
11031112
case ForceAndBridgeToObjC: {
11041113
auto &tl = SGF.getTypeLowering(value.getType());
11051114
auto sourceValueType = getBridgingSourceType().getOptionalObjectType();
1106-
value = SGF.emitCheckedGetOptionalValueFrom(loc, value, tl, SGFContext());
1115+
value = SGF.emitCheckedGetOptionalValueFrom(loc, value,
1116+
/*isImplicitUnwrap*/ true,
1117+
tl, SGFContext());
11071118
return SGF.emitNativeToBridgedValue(loc, value, sourceValueType,
11081119
getBridgingResultType(),
11091120
getBridgingLoweredResultType(), C);
@@ -1438,7 +1449,11 @@ Lowering::emitPeepholedConversions(SILGenFunction &SGF, SILLocation loc,
14381449

14391450
auto value = produceOrigValue(SGF, loc, SGFContext());
14401451
auto &optTL = SGF.getTypeLowering(value.getType());
1441-
return SGF.emitCheckedGetOptionalValueFrom(loc, value, optTL, C);
1452+
// isForceUnwrap is hardcoded true because hint.isForced() is only
1453+
// set by implicit force unwraps.
1454+
return SGF.emitCheckedGetOptionalValueFrom(loc, value,
1455+
/*isForceUnwrap*/ true,
1456+
optTL, C);
14421457
};
14431458

14441459
auto getBridgingSourceType = [&] {

lib/SILGen/SILGenExpr.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5165,7 +5165,9 @@ RValue RValueEmitter::emitForceValue(ForceValueExpr *loc, Expr *E,
51655165
// If this is an implicit force of an ImplicitlyUnwrappedOptional,
51665166
// and we're emitting into an unbridging conversion, try adjusting the
51675167
// context.
5168-
if (loc->isImplicit() && loc->isForceOfImplicitlyUnwrappedOptional()) {
5168+
bool isImplicitUnwrap = loc->isImplicit() &&
5169+
loc->isForceOfImplicitlyUnwrappedOptional();
5170+
if (isImplicitUnwrap) {
51695171
if (auto conv = C.getAsConversion()) {
51705172
if (auto adjusted = conv->getConversion().adjustForInitialForceValue()) {
51715173
auto value =
@@ -5182,7 +5184,7 @@ RValue RValueEmitter::emitForceValue(ForceValueExpr *loc, Expr *E,
51825184
const TypeLowering &optTL = SGF.getTypeLowering(E->getType());
51835185
ManagedValue opt = SGF.emitRValueAsSingleValue(E);
51845186
ManagedValue V =
5185-
SGF.emitCheckedGetOptionalValueFrom(loc, opt, optTL, C);
5187+
SGF.emitCheckedGetOptionalValueFrom(loc, opt, isImplicitUnwrap, optTL, C);
51865188
return RValue(SGF, loc, valueType->getCanonicalType(), V);
51875189
}
51885190

@@ -5695,8 +5697,10 @@ void SILGenFunction::emitIgnoredExpr(Expr *E) {
56955697

56965698
for (auto &FVE : reversed(forceValueExprs)) {
56975699
const TypeLowering &optTL = getTypeLowering(FVE->getSubExpr()->getType());
5700+
bool isImplicitUnwrap = FVE->isImplicit() &&
5701+
FVE->isForceOfImplicitlyUnwrappedOptional();
56985702
value = emitCheckedGetOptionalValueFrom(
5699-
FVE, value, optTL, SGFContext::AllowImmediatePlusZero);
5703+
FVE, value, isImplicitUnwrap, optTL, SGFContext::AllowImmediatePlusZero);
57005704
}
57015705
return;
57025706
}

lib/SILGen/SILGenFunction.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,13 +810,15 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
810810
/// _diagnoseUnexpectedNilOptional if the optional has no value. Return the
811811
/// MangedValue resulting from the success case.
812812
ManagedValue emitPreconditionOptionalHasValue(SILLocation loc,
813-
ManagedValue optional);
813+
ManagedValue optional,
814+
bool isImplicitUnwrap);
814815

815816
/// \brief Emit a call to the library intrinsic _getOptionalValue
816817
/// given the address of the optional, which checks that an optional contains
817818
/// some value and either returns the value or traps if there is none.
818819
ManagedValue emitCheckedGetOptionalValueFrom(SILLocation loc,
819820
ManagedValue addr,
821+
bool isImplicitUnwrap,
820822
const TypeLowering &optTL,
821823
SGFContext C);
822824

lib/SILGen/SILGenLValue.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -688,19 +688,22 @@ namespace {
688688
/// A physical path component which force-projects the address of
689689
/// the value of an optional l-value.
690690
class ForceOptionalObjectComponent : public PhysicalPathComponent {
691+
bool isImplicitUnwrap;
691692
public:
692-
ForceOptionalObjectComponent(LValueTypeData typeData)
693-
: PhysicalPathComponent(typeData, OptionalObjectKind) {}
693+
ForceOptionalObjectComponent(LValueTypeData typeData,
694+
bool isImplicitUnwrap)
695+
: PhysicalPathComponent(typeData, OptionalObjectKind),
696+
isImplicitUnwrap(isImplicitUnwrap) {}
694697

695698
ManagedValue offset(SILGenFunction &SGF, SILLocation loc, ManagedValue base,
696699
AccessKind accessKind) && override {
697700
// Assert that the optional value is present and return the projected out
698701
// payload.
699-
return SGF.emitPreconditionOptionalHasValue(loc, base);
702+
return SGF.emitPreconditionOptionalHasValue(loc, base, isImplicitUnwrap);
700703
}
701704

702705
void dump(raw_ostream &OS, unsigned indent) const override {
703-
OS.indent(indent) << "ForceOptionalObjectComponent()\n";
706+
OS.indent(indent) << "ForceOptionalObjectComponent(" << isImplicitUnwrap << ")\n";
704707
}
705708
};
706709

@@ -3004,7 +3007,9 @@ LValue SILGenLValue::visitForceValueExpr(ForceValueExpr *e,
30043007
LValue lv = visitRec(e->getSubExpr(), accessKind,
30053008
options.forComputedBaseLValue());
30063009
LValueTypeData typeData = getOptionalObjectTypeData(SGF, lv.getTypeData());
3007-
lv.add<ForceOptionalObjectComponent>(typeData);
3010+
bool isImplicitUnwrap = e->isImplicit() &&
3011+
e->isForceOfImplicitlyUnwrappedOptional();
3012+
lv.add<ForceOptionalObjectComponent>(typeData, isImplicitUnwrap);
30083013
return lv;
30093014
}
30103015

lib/SILGen/SILGenPoly.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,10 @@ ManagedValue Transform::transform(ManagedValue v,
398398
// optional or Any, force it.
399399
if (inputIsOptional && !outputIsOptional &&
400400
!outputSubstType->isExistentialType()) {
401+
// isImplicitUnwrap is hardcoded false because this method is never
402+
// used to generate code from a ForceValueExpr.
401403
v = SGF.emitCheckedGetOptionalValueFrom(Loc, v,
404+
/*isImplicitUnwrap*/ false,
402405
SGF.getTypeLowering(v.getType()),
403406
SGFContext());
404407

stdlib/private/StdlibUnittest/StdlibUnittest.swift

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -819,17 +819,17 @@ public func expectNotNil<T>(_ value: T?,
819819
return value
820820
}
821821

822-
public func expectCrashLater() {
822+
public func expectCrashLater(withMessage message: String = "") {
823823
print("\(_stdlibUnittestStreamPrefix);expectCrash;\(_anyExpectFailed)")
824824

825825
var stderr = _Stderr()
826-
print("\(_stdlibUnittestStreamPrefix);expectCrash", to: &stderr)
826+
print("\(_stdlibUnittestStreamPrefix);expectCrash;\(message)", to: &stderr)
827827

828828
_seenExpectCrash = true
829829
}
830830

831-
public func expectCrash(executing: () -> Void) -> Never {
832-
expectCrashLater()
831+
public func expectCrash(withMessage message: String = "", executing: () -> Void) -> Never {
832+
expectCrashLater(withMessage: message)
833833
executing()
834834
expectUnreachable()
835835
fatalError()
@@ -1080,6 +1080,7 @@ struct _ParentProcess {
10801080

10811081
var stdoutSeenCrashDelimiter = false
10821082
var stderrSeenCrashDelimiter = false
1083+
var expectingPreCrashMessage = ""
10831084
var stdoutEnd = false
10841085
var stderrEnd = false
10851086
var capturedCrashStdout: [Substring] = []
@@ -1090,14 +1091,16 @@ struct _ParentProcess {
10901091
var line = line[...]
10911092
if let index = findSubstring(line, _stdlibUnittestStreamPrefix) {
10921093
let controlMessage =
1093-
line[index..<line.endIndex].split(separator: ";")
1094+
line[index..<line.endIndex].split(separator: ";",
1095+
omittingEmptySubsequences: false)
10941096
switch controlMessage[1] {
10951097
case "expectCrash":
10961098
if isStdout {
10971099
stdoutSeenCrashDelimiter = true
10981100
anyExpectFailedInChild = controlMessage[2] == "true"
10991101
} else {
11001102
stderrSeenCrashDelimiter = true
1103+
expectingPreCrashMessage = String(controlMessage[2])
11011104
}
11021105
case "end":
11031106
if isStdout {
@@ -1114,6 +1117,11 @@ struct _ParentProcess {
11141117
return (done: stdoutEnd && stderrEnd, ())
11151118
}
11161119
}
1120+
if !expectingPreCrashMessage.isEmpty
1121+
&& findSubstring(line, expectingPreCrashMessage) != nil {
1122+
line = "OK: saw expected pre-crash message in \"\(line)\""[...]
1123+
expectingPreCrashMessage = ""
1124+
}
11171125
if isStdout {
11181126
if stdoutSeenCrashDelimiter {
11191127
capturedCrashStdout.append(line)
@@ -1122,7 +1130,16 @@ struct _ParentProcess {
11221130
if stderrSeenCrashDelimiter {
11231131
capturedCrashStderr.append(line)
11241132
if findSubstring(line, _crashedPrefix) != nil {
1125-
line = "OK: saw expected \"\(line.lowercased())\""[...]
1133+
if !expectingPreCrashMessage.isEmpty {
1134+
line = """
1135+
FAIL: saw expected "\(line.lowercased())", but without \
1136+
message "\(expectingPreCrashMessage)" before it
1137+
"""[...]
1138+
anyExpectFailedInChild = true
1139+
}
1140+
else {
1141+
line = "OK: saw expected \"\(line.lowercased())\""[...]
1142+
}
11261143
}
11271144
}
11281145
}
@@ -1152,8 +1169,8 @@ struct _ParentProcess {
11521169
}
11531170
return (
11541171
anyExpectFailedInChild,
1155-
stdoutSeenCrashDelimiter || stderrSeenCrashDelimiter, status,
1156-
capturedCrashStdout, capturedCrashStderr)
1172+
stdoutSeenCrashDelimiter || stderrSeenCrashDelimiter,
1173+
status, capturedCrashStdout, capturedCrashStderr)
11571174
}
11581175

11591176
// We reached EOF on stdout and stderr and we did not see "end" markers, so
@@ -1163,8 +1180,8 @@ struct _ParentProcess {
11631180
let status = _waitForChild()
11641181
return (
11651182
anyExpectFailedInChild,
1166-
stdoutSeenCrashDelimiter || stderrSeenCrashDelimiter, status,
1167-
capturedCrashStdout, capturedCrashStderr)
1183+
stdoutSeenCrashDelimiter || stderrSeenCrashDelimiter,
1184+
status, capturedCrashStdout, capturedCrashStderr)
11681185
}
11691186

11701187
internal mutating func _shutdownChild() -> (failed: Bool, Void) {

stdlib/public/core/Optional.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,12 @@ public // COMPILER_INTRINSIC
299299
func _diagnoseUnexpectedNilOptional(_filenameStart: Builtin.RawPointer,
300300
_filenameLength: Builtin.Word,
301301
_filenameIsASCII: Builtin.Int1,
302-
_line: Builtin.Word) {
302+
_line: Builtin.Word,
303+
_isImplicitUnwrap: Builtin.Int1) {
303304
_preconditionFailure(
304-
"Unexpectedly found nil while unwrapping an Optional value",
305+
Bool(_isImplicitUnwrap)
306+
? "Unexpectedly found nil while implicitly unwrapping an Optional value"
307+
: "Unexpectedly found nil while unwrapping an Optional value",
305308
file: StaticString(_start: _filenameStart,
306309
utf8CodeUnitCount: _filenameLength,
307310
isASCII: _filenameIsASCII),

test/SILGen/objc_bridging_peephole.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func testNonNullMethodResult(dummy: DummyClass) {
7575
// CHECK-NEXT: switch_enum [[RESULT]]
7676
//
7777
// CHECK: bb1:
78-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
78+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
7979
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
8080
// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
8181
// CHECK: [[USE:%.*]] = function_ref @$S22objc_bridging_peephole5useNSyySo8NSStringCF
@@ -86,7 +86,7 @@ func testNonNullMethodResult(dummy: DummyClass) {
8686
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
8787
// CHECK-NEXT: switch_enum [[RESULT]]
8888
// CHECK: bb3:
89-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
89+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
9090
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
9191
// CHECK-NEXT: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
9292
// CHECK-NEXT: [[BORROWED_ANYOBJECT:%.*]] = begin_borrow [[ANYOBJECT]]
@@ -104,7 +104,7 @@ func testForcedMethodResult(dummy: DummyClass) {
104104
// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
105105
// CHECK-NEXT: switch_enum [[RESULT]]
106106
// CHECK: bb1:
107-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
107+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
108108
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
109109
// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
110110
// CHECK: [[USE:%.*]] = function_ref @$S22objc_bridging_peephole5useNSyySo8NSStringCF
@@ -197,7 +197,7 @@ func testNonNullPropertyValue(dummy: DummyClass) {
197197
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
198198
// CHECK: switch_enum [[RESULT]]
199199
// CHECK: bb1:
200-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
200+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
201201
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
202202
// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
203203
// CHECK: [[USE:%.*]] = function_ref @$S22objc_bridging_peephole5useNSyySo8NSStringCF
@@ -208,7 +208,7 @@ func testNonNullPropertyValue(dummy: DummyClass) {
208208
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
209209
// CHECK: switch_enum [[RESULT]]
210210
// CHECK: bb3:
211-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
211+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
212212
// CHECK: bb4([[RESULT:%.*]] : @owned $NSString):
213213
// CHECK: [[ANYOBJECT:%.*]] = init_existential_ref [[RESULT]] : $NSString : $NSString, $AnyObject
214214
// CHECK: [[BORROWED_ANYOBJECT:%.*]] = begin_borrow [[ANYOBJECT]]
@@ -226,7 +226,7 @@ func testForcedPropertyValue(dummy: DummyClass) {
226226
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[SELF]])
227227
// CHECK: switch_enum [[RESULT]]
228228
// CHECK: bb1:
229-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
229+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
230230
// CHECK: bb2([[RESULT:%.*]] : @owned $NSString):
231231
// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
232232
// CHECK: [[USE:%.*]] = function_ref @$S22objc_bridging_peephole5useNSyySo8NSStringCF
@@ -281,7 +281,7 @@ func testNonnullSubscriptGet(object: NonnullSubscript, index: AnyObject) {
281281
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
282282
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
283283
// CHECK-NEXT: switch_enum [[RESULT]]
284-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
284+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
285285
// CHECK: bb{{[0-9]+}}([[RESULT:%.*]] : @owned $NSString):
286286
// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
287287
// CHECK: [[USE:%.*]] = function_ref @$S22objc_bridging_peephole5useNSyySo8NSStringCF
@@ -326,7 +326,7 @@ func testNullproneSubscriptGet(object: NullproneSubscript, index: AnyObject) {
326326
// CHECK: [[RESULT:%.*]] = apply [[METHOD]]([[INDEX]], [[SELF]])
327327
// CHECK-NEXT: destroy_value [[INDEX]] : $AnyObject
328328
// CHECK-NEXT: switch_enum [[RESULT]]
329-
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_lineyBp_BwBi1_BwtF
329+
// CHECK: function_ref @$Ss30_diagnoseUnexpectedNilOptional14_filenameStart01_E6Length01_E7IsASCII5_line17_isImplicitUnwrapyBp_BwBi1_BwBi1_tF
330330
// CHECK: bb{{[0-9]+}}([[RESULT:%.*]] : @owned $NSString):
331331
// CHECK: [[BORROWED_RESULT:%.*]] = begin_borrow [[RESULT]]
332332
// CHECK: [[USE:%.*]] = function_ref @$S22objc_bridging_peephole5useNSyySo8NSStringCF

0 commit comments

Comments
 (0)