@@ -1972,45 +1972,63 @@ static bool isPolymorphic(const AbstractStorageDecl *storage) {
1972
1972
return false ;
1973
1973
}
1974
1974
1975
- static bool isDirectToStorageAccess (const AccessorDecl *accessor ,
1975
+ static bool isDirectToStorageAccess (const DeclContext *UseDC ,
1976
1976
const VarDecl *var, bool isAccessOnSelf) {
1977
- // All accesses have ordinary semantics except those to variables
1978
- // with storage from within their own accessors.
1979
- if (accessor->getStorage () != var)
1977
+ if (!var->hasStorage ())
1980
1978
return false ;
1981
1979
1982
- if (!var->hasStorage ())
1980
+ auto *AFD = dyn_cast<AbstractFunctionDecl>(UseDC);
1981
+ if (AFD == nullptr )
1983
1982
return false ;
1984
1983
1985
- // In Swift 5 and later, the access must also be a member access on 'self'.
1986
- if (!isAccessOnSelf &&
1987
- var->getDeclContext ()->isTypeContext () &&
1988
- var->getASTContext ().isSwiftVersionAtLeast (5 ))
1984
+ // The property reference is for immediate class, not a derived class.
1985
+ if (AFD->getParent ()->getSelfNominalTypeDecl () !=
1986
+ var->getDeclContext ()->getSelfNominalTypeDecl ())
1989
1987
return false ;
1990
1988
1991
- // As a special case, 'read' and 'modify' coroutines with forced static
1992
- // dispatch must use ordinary semantics, so that the 'modify' coroutine for a
1993
- // 'dynamic' property uses Objective-C message sends and not direct access to
1994
- // storage.
1995
- if (accessor->hasForcedStaticDispatch ())
1989
+ // If the storage is resilient, we cannot access it directly at all.
1990
+ if (var->isResilient (UseDC->getParentModule (),
1991
+ UseDC->getResilienceExpansion ()))
1996
1992
return false ;
1997
1993
1998
- return true ;
1994
+ if (isa<ConstructorDecl>(AFD) || isa<DestructorDecl>(AFD)) {
1995
+ // The access must also be a member access on 'self' in all language modes.
1996
+ if (!isAccessOnSelf)
1997
+ return false ;
1998
+
1999
+ return true ;
2000
+ } else if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
2001
+ // The accessor must be for the variable itself.
2002
+ if (accessor->getStorage () != var)
2003
+ return false ;
2004
+
2005
+ // In Swift 5 and later, the access must also be a member access on 'self'.
2006
+ if (!isAccessOnSelf &&
2007
+ var->getDeclContext ()->isTypeContext () &&
2008
+ var->getASTContext ().isSwiftVersionAtLeast (5 ))
2009
+ return false ;
2010
+
2011
+ // As a special case, 'read' and 'modify' coroutines with forced static
2012
+ // dispatch must use ordinary semantics, so that the 'modify' coroutine for a
2013
+ // 'dynamic' property uses Objective-C message sends and not direct access to
2014
+ // storage.
2015
+ if (accessor->hasForcedStaticDispatch ())
2016
+ return false ;
2017
+
2018
+ return true ;
2019
+ }
2020
+
2021
+ return false ;
1999
2022
}
2000
2023
2001
2024
// / Determines the access semantics to use in a DeclRefExpr or
2002
2025
// / MemberRefExpr use of this value in the specified context.
2003
2026
AccessSemantics
2004
2027
ValueDecl::getAccessSemanticsFromContext (const DeclContext *UseDC,
2005
2028
bool isAccessOnSelf) const {
2006
- // The condition most likely to fast-path us is not being in an accessor,
2007
- // so we check that first.
2008
- if (auto *accessor = dyn_cast<AccessorDecl>(UseDC)) {
2009
- if (auto *var = dyn_cast<VarDecl>(this )) {
2010
- if (isDirectToStorageAccess (accessor, var, isAccessOnSelf))
2011
- return AccessSemantics::DirectToStorage;
2012
- }
2013
- }
2029
+ if (auto *var = dyn_cast<VarDecl>(this ))
2030
+ if (isDirectToStorageAccess (UseDC, var, isAccessOnSelf))
2031
+ return AccessSemantics::DirectToStorage;
2014
2032
2015
2033
// Otherwise, it's a semantically normal access. The client should be
2016
2034
// able to figure out the most efficient way to do this access.
0 commit comments