Skip to content

Commit 3a7b2c3

Browse files
committed
Revert r21706 "Stop checking for 'nil' returns from non-failable Objective-C initializers."
Swift SVN r21712
1 parent c504086 commit 3a7b2c3

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4641,6 +4641,30 @@ RValue RValueEmitter::visitRebindSelfInConstructorExpr(
46414641
break;
46424642
}
46434643
SGF.SelfInitDelegationState = SILGenFunction::NormalSelf;
4644+
4645+
// If we are using Objective-C allocation, the caller can return
4646+
// nil. When this happens with an explicitly-written super.init or
4647+
// self.init invocation, return early if we did get nil.
4648+
//
4649+
// TODO: Remove this when failable initializers are fully implemented.
4650+
auto classDecl = selfTy->getClassOrBoundGenericClass();
4651+
if (classDecl && !E->getSubExpr()->isImplicit() &&
4652+
usesObjCAllocator(classDecl)) {
4653+
// Check whether the new self is null.
4654+
SILValue isNonnullSelf = SGF.B.createIsNonnull(E, newSelf.getValue());
4655+
Condition cond = SGF.emitCondition(isNonnullSelf, E,
4656+
/*hasFalseCode=*/false,
4657+
/*invertValue=*/true,
4658+
{ });
4659+
4660+
// If self is null, branch to the epilog.
4661+
cond.enterTrue(SGF.B);
4662+
SGF.Cleanups.emitBranchAndCleanups(SGF.ReturnDest, E, { });
4663+
cond.exitTrue(SGF.B);
4664+
4665+
cond.complete(SGF.B);
4666+
}
4667+
46444668
return SGF.emitEmptyTupleRValue(E);
46454669
}
46464670

test/SILGen/objc_thunks.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,17 @@ class Hoozit : Gizmo {
193193
// CHECK-NOT: unconditional_checked_cast downcast [[SELF_REPLACED]] : $Gizmo to $Hoozit
194194
// CHECK: unchecked_ref_cast
195195
// CHECK-NEXT: store [[SELF:%[0-9]+]] to [[SELF_BOX]]#1 : $*Hoozit
196+
// CHECK-NEXT: [[NONNULL:%[0-9]+]] = is_nonnull [[SELF]] : $Hoozit
197+
// CHECK-NEXT: cond_br [[NONNULL]], [[NONNULL_BB:bb[0-9]+]], [[NULL_BB:bb[0-9]+]]
198+
// CHECK: [[NULL_BB]]:
199+
// CHECK: br [[EPILOG_BB:bb[0-9]+]]
200+
201+
// CHECK: [[NONNULL_BB]]:
196202
// CHECK: [[OTHER_REF:%[0-9]+]] = function_ref @_TF11objc_thunks5otherFT_T_ : $@thin () -> ()
197203
// CHECK-NEXT: apply [[OTHER_REF]]() : $@thin () -> ()
204+
// CHECK-NEXT: br [[EPILOG_BB]]
205+
206+
// CHECK: [[EPILOG_BB]]:
198207
// CHECK-NOT: super_method
199208
// CHECK: return
200209
override init(bellsOn x : Int) {
@@ -259,9 +268,19 @@ extension Hoozit {
259268
// CHECK: [[CTOR:%[0-9]+]] = class_method [volatile] [[SELF:%[0-9]+]] : $Hoozit, #Hoozit.init!initializer.1.foreign : Hoozit.Type -> (int: Int) -> Hoozit , $@cc(objc_method) @thin (Int, @owned Hoozit) -> @owned Hoozit
260269
// CHECK: [[NEW_SELF:%[0-9]+]] = apply [[CTOR]]
261270
// CHECK: store [[NEW_SELF]] to [[SELF_BOX]]#1 : $*Hoozit
262-
// CHECK: [[OTHER_REF:%[0-9]+]] = function_ref @_TF11objc_thunks5otherFT_T_ : $@thin () -> ()
271+
// CHECK: [[NONNULL:%[0-9]+]] = is_nonnull [[NEW_SELF]] : $Hoozit
272+
// CHECK-NEXT: cond_br [[NONNULL]], [[NONNULL_BB:bb[0-9]+]], [[NULL_BB:bb[0-9]+]]
273+
// CHECK: [[NULL_BB]]:
274+
// CHECK-NEXT: strong_release [[X_BOX]]#0 : $Builtin.NativeObject
275+
// CHECK-NEXT: br [[EPILOG_BB:bb[0-9]+]]
276+
277+
// CHECK: [[NONNULL_BB]]:
278+
// CHECK: [[OTHER_REF:%[0-9]+]] = function_ref @_TF11objc_thunks5otherFT_T_ : $@thin () -> ()
263279
// CHECK-NEXT: apply [[OTHER_REF]]() : $@thin () -> ()
264280
// CHECK-NEXT: strong_release [[X_BOX]]#0 : $Builtin.NativeObject
281+
// CHECK-NEXT: br [[EPILOG_BB]]
282+
283+
// CHECK: [[EPILOG_BB]]:
265284
// CHECK-NOT: super_method
266285
// CHECK: return
267286
self.init(int:Int(d))

0 commit comments

Comments
 (0)