mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Sema: Synthesize materializeForSet with dynamically-dispatched accessors for dynamic properties.
Semantically, a dynamic property must always be dispatched in case it gets replaced at runtime, and an @NSManaged property may not have static accessors at all. Use ordinary access to the computed property accessors in materializeForSet when a property is dynamic or ObjC-originated. More rdar://problem/18706056. There's still a problem--we try to vtable-dispatch materializeForSet, which is redundant for native classes, but impossible for imported ObjC classes. We should suppress this, but trying to make materializeForSet "final" breaks subclassing if the property is overridden. This time, update test/SILGen/objc_properties.swift to avoid a false negative test failure. Swift SVN r24888
This commit is contained in:
@@ -1111,10 +1111,18 @@ static void synthesizeComputedMaterializeForSet(FuncDecl *materializeForSet,
|
||||
ASTContext &ctx = TC.Context;
|
||||
|
||||
SmallVector<ASTNode, 4> body;
|
||||
|
||||
AccessSemantics semantics;
|
||||
// If the storage is dynamic, we must dynamically redispatch through the
|
||||
// accessor. Otherwise, we can do a direct peer access.
|
||||
if (storage->isDynamic())
|
||||
semantics = AccessSemantics::Ordinary;
|
||||
else
|
||||
semantics = AccessSemantics::DirectToAccessor;
|
||||
|
||||
// Builtin.initialize(self.property, buffer)
|
||||
Expr *curValue = buildStorageReference(materializeForSet, storage,
|
||||
AccessSemantics::DirectToAccessor,
|
||||
semantics,
|
||||
SelfAccessKind::Peer, TC);
|
||||
Expr *bufferRef = new (ctx) DeclRefExpr(bufferDecl, SourceLoc(), IsImplicit);
|
||||
body.push_back(buildCallToBuiltin(ctx, "initialize",
|
||||
@@ -1144,7 +1152,7 @@ static void synthesizeComputedMaterializeForSet(FuncDecl *materializeForSet,
|
||||
Expr *storageRef =
|
||||
buildStorageReference(
|
||||
CallbackStorageReferenceContext{selfDecl, callbackStorageDecl},
|
||||
storage, AccessSemantics::DirectToAccessor,
|
||||
storage, semantics,
|
||||
SelfAccessKind::Peer, TC);
|
||||
body.push_back(new (ctx) AssignExpr(storageRef, SourceLoc(),
|
||||
value, IsImplicit));
|
||||
@@ -1362,11 +1370,12 @@ void swift::synthesizeMaterializeForSet(FuncDecl *materializeForSet,
|
||||
llvm_unreachable("no accessors");
|
||||
|
||||
// We can use direct access to stored variables, but not if they're
|
||||
// weak or unowned.
|
||||
// weak, unowned, or dynamic.
|
||||
case AbstractStorageDecl::StoredWithTrivialAccessors: {
|
||||
// Only variables can be Stored, and only variables can be weak/unowned.
|
||||
auto var = cast<VarDecl>(storage);
|
||||
if (var->getType()->is<ReferenceStorageType>()) {
|
||||
if (var->getType()->is<ReferenceStorageType>()
|
||||
|| var->isDynamic()) {
|
||||
synthesizeComputedMaterializeForSet(materializeForSet, storage,
|
||||
bufferDecl, TC);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user