Skip to content

Commit 4f927c4

Browse files
authored
Merge pull request #8008 from gottesmm/init_existential_ref_fix
2 parents 0d2c17f + 0769239 commit 4f927c4

File tree

5 files changed

+45
-34
lines changed

5 files changed

+45
-34
lines changed

lib/SILGen/SILGenBuilder.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ InitExistentialRefInst *SILGenBuilder::createInitExistentialRef(
192192
loc, existentialType, formalConcreteType, concreteValue, conformances);
193193
}
194194

195+
ManagedValue SILGenBuilder::createInitExistentialRef(
196+
SILLocation Loc, SILType ExistentialType, CanType FormalConcreteType,
197+
ManagedValue Concrete, ArrayRef<ProtocolConformanceRef> Conformances) {
198+
CleanupCloner Cloner(*this, Concrete);
199+
InitExistentialRefInst *IERI =
200+
createInitExistentialRef(Loc, ExistentialType, FormalConcreteType,
201+
Concrete.forward(gen), Conformances);
202+
return Cloner.clone(IERI);
203+
}
204+
195205
AllocExistentialBoxInst *SILGenBuilder::createAllocExistentialBox(
196206
SILLocation loc, SILType existentialType, CanType concreteType,
197207
ArrayRef<ProtocolConformanceRef> conformances) {

lib/SILGen/SILGenBuilder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ class SILGenBuilder : public SILBuilder {
104104
CanType formalConcreteType, SILValue concreteValue,
105105
ArrayRef<ProtocolConformanceRef> conformances);
106106

107+
ManagedValue
108+
createInitExistentialRef(SILLocation loc, SILType existentialType,
109+
CanType formalConcreteType, ManagedValue concrete,
110+
ArrayRef<ProtocolConformanceRef> conformances);
111+
107112
AllocExistentialBoxInst *
108113
createAllocExistentialBox(SILLocation loc, SILType existentialType,
109114
CanType concreteType,

lib/SILGen/SILGenConvert.cpp

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,7 @@ ManagedValue SILGenFunction::emitExistentialErasure(
463463
if (nsErrorType->isExactSuperclassOf(concreteFormalType, nullptr)) {
464464
ManagedValue nsError = F(SGFContext());
465465
if (nsErrorType != concreteFormalType) {
466-
nsError = ManagedValue(B.createUpcast(loc, nsError.getValue(),
467-
getLoweredType(nsErrorType)),
468-
nsError.getCleanup());
466+
nsError = B.createUpcast(loc, nsError, getLoweredType(nsErrorType));
469467
}
470468
return emitBridgedToNativeError(loc, nsError);
471469
}
@@ -490,16 +488,15 @@ ManagedValue SILGenFunction::emitExistentialErasure(
490488
}
491489
}
492490

493-
auto nativeError = F(SGFContext());
491+
ManagedValue nativeError = F(SGFContext());
494492

495493
FormalEvaluationScope writebackScope(*this);
496-
auto nsError =
497-
emitRValueForPropertyLoad(loc, nativeError, concreteFormalType,
498-
/*super*/ false, nsErrorVar,
499-
nsErrorVarSubstitutions,
500-
AccessSemantics::Ordinary, nsErrorType,
501-
SGFContext())
502-
.getAsSingleValue(*this, loc);
494+
ManagedValue nsError =
495+
emitRValueForPropertyLoad(
496+
loc, nativeError, concreteFormalType,
497+
/*super*/ false, nsErrorVar, nsErrorVarSubstitutions,
498+
AccessSemantics::Ordinary, nsErrorType, SGFContext())
499+
.getAsSingleValue(*this, loc);
503500

504501
return emitBridgedToNativeError(loc, nsError);
505502
}
@@ -557,14 +554,11 @@ ManagedValue SILGenFunction::emitExistentialErasure(
557554
// layering reasons, so perform an unchecked cast down to NSError.
558555
SILType anyObjectTy =
559556
potentialNSError.getType().getAnyOptionalObjectType();
560-
SILValue nsError = isPresentBB->createPHIArgument(
561-
anyObjectTy, ValueOwnershipKind::Owned);
557+
ManagedValue nsError = B.createOwnedPHIArgument(anyObjectTy);
562558
nsError = B.createUncheckedRefCast(loc, nsError,
563559
getLoweredType(nsErrorType));
564560

565-
branchArg = emitBridgedToNativeError(loc,
566-
emitManagedRValueWithCleanup(nsError))
567-
.forward(*this);
561+
branchArg = emitBridgedToNativeError(loc, nsError).forward(*this);
568562
}
569563
B.createBranch(loc, contBB, branchArg);
570564

@@ -616,12 +610,8 @@ ManagedValue SILGenFunction::emitExistentialErasure(
616610
assert(existentialTL.isLoadable());
617611

618612
ManagedValue sub = F(SGFContext());
619-
SILValue v = B.createInitExistentialRef(loc,
620-
existentialTL.getLoweredType(),
621-
concreteFormalType,
622-
sub.getValue(),
623-
conformances);
624-
return ManagedValue(v, sub.getCleanup());
613+
return B.createInitExistentialRef(loc, existentialTL.getLoweredType(),
614+
concreteFormalType, sub, conformances);
625615
}
626616
case ExistentialRepresentation::Boxed: {
627617
// Allocate the existential.
@@ -660,13 +650,10 @@ ManagedValue SILGenFunction::emitExistentialErasure(
660650
ProtocolConformanceRef buf[] = {
661651
*anyObjectConformance,
662652
};
663-
664-
auto asAnyObject = B.createInitExistentialRef(loc,
665-
SILType::getPrimitiveObjectType(anyObjectTy),
666-
concreteFormalType,
667-
concreteValue.getValue(),
668-
getASTContext().AllocateCopy(buf));
669-
return ManagedValue(asAnyObject, concreteValue.getCleanup());
653+
654+
return B.createInitExistentialRef(
655+
loc, SILType::getPrimitiveObjectType(anyObjectTy), concreteFormalType,
656+
concreteValue, getASTContext().AllocateCopy(buf));
670657
};
671658

672659
auto concreteTLPtr = &concreteTL;

test/SILGen/dynamic_self.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func testExistentialDispatch(p: P) {
9494
// CHECK: [[CP_F:%[0-9]+]] = witness_method $@opened([[N]]) CP, #CP.f!1 : {{.*}}, [[CP_ADDR]]{{.*}} : $@convention(witness_method) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
9595
// CHECK: [[CP_F_RESULT:%[0-9]+]] = apply [[CP_F]]<@opened([[N]]) CP>([[CP_ADDR]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : CP> (@guaranteed τ_0_0) -> @owned τ_0_0
9696
// CHECK: [[RESULT_EXISTENTIAL:%[0-9]+]] = init_existential_ref [[CP_F_RESULT]] : $@opened([[N]]) CP : $@opened([[N]]) CP, $CP
97-
// CHECK: destroy_value [[CP_F_RESULT]] : $@opened([[N]]) CP
97+
// CHECK: destroy_value [[RESULT_EXISTENTIAL]]
9898
// CHECK: end_borrow [[BORROWED_CP]] from [[CP]]
9999
// CHECK: destroy_value [[CP]]
100100
func testExistentialDispatchClass(cp: CP) {

test/SILGen/objc_error.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,20 @@ class MyNSError : NSError {
111111
}
112112
}
113113

114-
// CHECK-LABEL: sil hidden @_T010objc_error14eraseMyNSError{{[_0-9a-zA-Z]*}}F
115-
// CHECK-NOT: return
116-
// CHECK: init_existential_ref
114+
// CHECK-LABEL: sil hidden @_T010objc_error14eraseMyNSError{{[_0-9a-zA-Z]*}}F : $@convention(thin) () -> @owned Error {
115+
// CHECK: bb0:
116+
// CHECK: [[NSERROR_SUBCLASS:%.*]] = apply {{.*}}({{.*}}) : $@convention(method) (@thick MyNSError.Type) -> @owned MyNSError
117+
// CHECK: [[UPCAST:%.*]] = upcast [[NSERROR_SUBCLASS]] : $MyNSError to $NSError
118+
// CHECK: [[EXISTENTIAL_REF:%.*]] = init_existential_ref [[UPCAST]]
119+
// CHECK: [[BORROWED_EXISTENTIAL_REF:%.*]] = begin_borrow [[EXISTENTIAL_REF]]
120+
// CHECK: [[COPY_BORROWED_EXISTENTIAL_REF:%.*]] = copy_value [[BORROWED_EXISTENTIAL_REF]]
121+
// CHECK: end_borrow [[BORROWED_EXISTENTIAL_REF]] from [[EXISTENTIAL_REF]]
122+
// CHECK: destroy_value [[EXISTENTIAL_REF]]
123+
// CHECK: return [[COPY_BORROWED_EXISTENTIAL_REF]]
124+
// CHECK: } // end sil function '_T010objc_error14eraseMyNSError{{[_0-9a-zA-Z]*}}F'
117125
func eraseMyNSError() -> Error {
118-
return MyNSError()
126+
let x: Error = MyNSError()
127+
return x
119128
}
120129

121130
// CHECK-LABEL: sil hidden @_T010objc_error25eraseFictionalServerErrors0F0_pyF

0 commit comments

Comments
 (0)