From e632c5ec9604bcd125cb5ed00879b82a4fa03c51 Mon Sep 17 00:00:00 2001 From: Ellie Shin Date: Wed, 15 May 2024 15:35:40 -0700 Subject: [PATCH] -Add package-cmo check to bypassResilienceInPackage method. -Fix SILDeclRef getLinkageLimit() for GlobalAccessor to return Limit::None if bypassResilienceInPackage is enabled. --- lib/AST/Decl.cpp | 28 +++++++++++++++++++--------- lib/SIL/IR/SILDeclRef.cpp | 8 ++++++-- lib/SIL/Verifier/SILVerifier.cpp | 30 ++++++++++++------------------ 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 46263924ce01c..64ac3f1e65ac4 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3060,7 +3060,7 @@ bool AbstractStorageDecl::isResilient(ModuleDecl *M, case ResilienceExpansion::Maximal: if (M == getModuleContext()) return false; - // Non-resilient if bypass optimization in package is enabled + // Access non-resiliently if package optimization is enabled if (bypassResilienceInPackage(M)) return false; return isResilient(); @@ -4271,13 +4271,23 @@ bool ValueDecl::hasOpenAccess(const DeclContext *useDC) const { } bool ValueDecl::bypassResilienceInPackage(ModuleDecl *accessingModule) const { - // Client needs to opt in to bypass resilience checks at the use site. - // Client and the loaded module both need to be in the same package. - // The loaded module needs to be built from source and opt in to allow - // non-resilient access. - return getASTContext().LangOpts.EnableBypassResilienceInPackage && - getModuleContext()->inSamePackage(accessingModule) && - getModuleContext()->allowNonResilientAccess(); + auto declModule = getModuleContext(); + if (declModule->inSamePackage(accessingModule) && + declModule->allowNonResilientAccess()) { + // If the defining module is built with package-cmo, + // allow direct access from the use site that belongs + // to accessingModule (client module). + if (declModule->isResilient() && + declModule->serializePackageEnabled()) + return true; + + // If not, check if the client can still opt in to + // have a direct access to this decl from the use + // site with a flag. + // FIXME: serialize this flag to Module and get it via accessingModule. + return getASTContext().LangOpts.EnableBypassResilienceInPackage; + } + return false; } /// Given the formal access level for using \p VD, compute the scope where @@ -5134,7 +5144,7 @@ bool NominalTypeDecl::isResilient(ModuleDecl *M, // non-resiliently in a maximal context. if (M == getModuleContext()) return false; - // Non-resilient if bypass optimization in package is enabled + // Access non-resiliently if package optimization is enabled if (bypassResilienceInPackage(M)) return false; diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 346c21e44e6e3..e2cc7b35bb4b2 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -460,8 +460,12 @@ static LinkageLimit getLinkageLimit(SILDeclRef constant) { case Kind::EnumElement: return Limit::OnDemand; - case Kind::GlobalAccessor: - return cast(d)->isResilient() ? Limit::NeverPublic : Limit::None; + case Kind::GlobalAccessor: { + auto varDecl = cast(d); + return varDecl->isResilient() && + !varDecl->getModuleContext()->allowNonResilientAccess() ? + Limit::NeverPublic : Limit::None; + } case Kind::DefaultArgGenerator: // If the default argument is to be serialized, only use non-ABI public diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index ba4ff6e1e3109..cff0aabacfffa 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -160,29 +160,23 @@ bool checkResilience(DeclType *D, ModuleDecl *accessingModule, ResilienceExpansion expansion, bool isSerializedForPackage) { auto declModule = D->getModuleContext(); - // Explicitly bypassed for debugging with `bypass-resilience-checks` + + // For DEBUGGING: this check looks up + // `bypass-resilience-checks`, which is + // an old flag used for debugging, and + // has nothing to do with optimizations. if (declModule->getBypassResilience()) return false; - // Check whether the function or a decl referenced - // by the function was serialized with package-cmo - // optimization. - // If enabled, resilience expansion for the function - // is maximal (see SILFunction::getResilienceExpansion()). + // If the SIL function containing the decl D is + // [serialized_for_package], package-cmo had been + // enabled in its defining module, so direct access + // from a client module should be allowed. if (accessingModule != declModule && - expansion == ResilienceExpansion::Maximal) { - // If the function is [serialized_for_package], - // package-cmo had been enabled in its defining - // module, so direct access should be allowed. - if (isSerializedForPackage) - return false; - // If not, check whether the referenced decl was - // serialized with package-cmo. - if (declModule->isResilient() && - declModule->serializePackageEnabled() && - declModule->inSamePackage(accessingModule)) + expansion == ResilienceExpansion::Maximal && + isSerializedForPackage) return false; - } + return D->isResilient(accessingModule, expansion); }