Skip to content

SILGen: Enclose formal evaluation of self in a type(of:) expression during an init delegation in a formal scope. #14200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2773,12 +2773,13 @@ static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
auto *vd = cast<ParamDecl>(dre->getDecl());
ManagedValue selfValue;

Scope S(SGF, loc);
Optional<FormalEvaluationScope> FES;
// If we have not exclusively borrowed self, we need to do so now.
if (SGF.SelfInitDelegationState == SILGenFunction::WillExclusiveBorrowSelf) {
// We need to use a full scope here to ensure that any underlying
// "normal cleanup" borrows are cleaned up.
Scope S(SGF, loc);
selfValue = S.popPreservingValue(SGF.emitRValueAsSingleValue(dre));
selfValue = SGF.emitRValueAsSingleValue(dre);
} else {
// If we already exclusively borrowed self, then we need to emit self
// using formal evaluation primitives.
Expand All @@ -2788,6 +2789,7 @@ static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
// This needs to be inlined since there is a Formal Evaluation Scope
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
FES.emplace(SGF);
selfValue =
SGF.emitLValueForDecl(dre, vd, dre->getType()->getCanonicalType(),
AccessKind::Read, dre->getAccessSemantics());
Expand All @@ -2796,9 +2798,7 @@ static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
selfValue.getLValueAddress(), ctx)
.getAsSingleValue(SGF, loc);
}
assert(selfValue && !selfValue.hasCleanup());

// Check if we need to perform a conversion here.
return SGF.B.createValueMetatype(loc, metaTy, selfValue.getValue());
}

Expand All @@ -2814,7 +2814,6 @@ SILValue SILGenFunction::emitMetatypeOfValue(SILLocation loc, Expr *baseExpr) {
SGFContext::AllowImmediatePlusZero).getValue();
return B.createExistentialMetatype(loc, metaTy, base);
}

SILType metaTy = getLoweredLoadableType(CanMetatypeType::get(baseTy));
// If the lowered metatype has a thick representation, we need to derive it
// dynamically from the instance.
Expand All @@ -2836,7 +2835,6 @@ SILValue SILGenFunction::emitMetatypeOfValue(SILLocation loc, Expr *baseExpr) {
return S.popPreservingValue(B.createValueMetatype(loc, metaTy, base))
.getValue();
}

// Otherwise, ignore the base and return the static thin metatype.
emitIgnoredExpr(baseExpr);
return B.createMetatype(loc, metaTy);
Expand Down
12 changes: 12 additions & 0 deletions test/SILGen/metatype_in_init_delegation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %target-swift-frontend -emit-silgen -verify %s
// REQUIRES: objc_interop

import Foundation
import CoreData

@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)
class Foo : NSManagedObject {
convenience init(context: NSManagedObjectContext, value: Int) {
self.init(entity: type(of: self).entity(), insertInto: context)
}
}