Compare the package names of the accessing module and the decl's defining module.

Update tests.
This commit is contained in:
Ellie Shin
2024-02-08 20:08:46 -08:00
parent f5150e7265
commit 7d4e5678c7
7 changed files with 52 additions and 43 deletions

View File

@@ -480,8 +480,8 @@ public:
return Identifier();
}
bool inPackage(std::string packageName) {
return !getPackageName().empty() && getPackageName().str() == packageName;
bool inSamePackage(ModuleDecl *other) {
return !getPackageName().empty() && getPackageName() == other->getPackageName();
}
/// Get the package associated with this module

View File

@@ -2957,14 +2957,16 @@ bool AbstractStorageDecl::isResilient() const {
if (getAttrs().hasAttribute<FixedLayoutAttr>())
return false;
// If we're an instance property of a nominal type, query the type.
if (!isStatic())
if (auto *nominalDecl = getDeclContext()->getSelfNominalTypeDecl())
return nominalDecl->isResilient();
// Non-public global and static variables always have a
// fixed layout.
if (!getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true).isPublicOrPackage())
auto accessScope = getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true);
if (!accessScope.isPublicOrPackage())
return false;
if (!getModuleContext()->isResilient())
@@ -2973,8 +2975,7 @@ bool AbstractStorageDecl::isResilient() const {
// Allows bypassing resilience checks for package decls
// at use site within a package if opted in, whether the
// loaded module was built resiliently or not.
return !getDeclContext()->bypassResilienceInPackage(getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true).isPackage());
return !getDeclContext()->bypassResilienceInPackage(accessScope.isPackage());
}
bool AbstractStorageDecl::isResilient(ModuleDecl *M,
@@ -5050,8 +5051,9 @@ bool NominalTypeDecl::isResilient() const {
// Allows bypassing resilience checks for package decls
// at use site within a package if opted in, whether the
// loaded module was built resiliently or not.
return !getDeclContext()->bypassResilienceInPackage(getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true).isPackage());
auto accessScope = getFormalAccessScope(/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true);
return !getDeclContext()->bypassResilienceInPackage(accessScope.isPackage());
}
DestructorDecl *NominalTypeDecl::getValueTypeDestructor() {

View File

@@ -302,12 +302,12 @@ PackageUnit *DeclContext::getPackageContext(bool lookupIfNotCurrent) const {
bool DeclContext::bypassResilienceInPackage(bool isForPackageDecl) const {
// Bypassing resilience checks only applies to package types (and possibly
// public types in a package in the future). Allowed only if opted-in for
// bypassing checks, client and defining module are in the same package,
// and defining module is a binary module.
// public types in the same package in the future). Allowed only if opted-in
// for bypassing optimization, client and defining module are in the same
// package, and defining module is a binary module.
return isForPackageDecl &&
getASTContext().LangOpts.EnableBypassResilienceInPackage &&
getParentModule()->inPackage(getASTContext().LangOpts.PackageName) &&
getParentModule()->inSamePackage(getASTContext().MainModule) &&
!getParentModule()->isBuiltFromInterface();
}

View File

@@ -349,6 +349,7 @@ bool NormalProtocolConformance::isResilient() const {
// individual witnesses.
if (!getDeclContext()->getSelfNominalTypeDecl()->isResilient())
return false;
return getDeclContext()->getParentModule()->isResilient();
}

View File

@@ -762,7 +762,7 @@ void UnboundImport::validateInterfaceWithPackageName(ModuleDecl *topLevelModule,
// If source file is .swift or non-interface, show diags when importing an interface file
ASTContext &ctx = topLevelModule->getASTContext();
if (topLevelModule->inPackage(ctx.LangOpts.PackageName) &&
if (topLevelModule->inSamePackage(ctx.MainModule) &&
topLevelModule->isBuiltFromInterface() &&
!topLevelModule->getModuleSourceFilename().endswith(".package.swiftinterface")) {
ctx.Diags.diagnose(import.module.getModulePath().front().Loc,

View File

@@ -221,7 +221,7 @@ public func memoryLayoutDotSizeWithResilientStruct() -> Int {
// CHECK-LABEL: define{{.*}} swiftcc {{i32|i64}} @"$s18package_resilience40memoryLayoutDotStrideWithResilientStructSiyF"()
public func memoryLayoutDotStrideWithResilientStruct() -> Int {
// CHECK: ret [[INT]] [[#WORDSIZE + WORDSIZE]]
return MemoryLayout<Size>.size
return MemoryLayout<Size>.stride
}
// CHECK-LABEL: define{{.*}} swiftcc {{i32|i64}} @"$s18package_resilience43memoryLayoutDotAlignmentWithResilientStructSiyF"()

View File

@@ -13,6 +13,17 @@
//--- Utils.swift
package enum PkgEnum {
case one
case two(Int)
}
@usableFromInline
package enum UfiPkgEnum {
case one
case two(Int)
}
public enum PublicEnum {
case one
case two(Int)
@@ -24,31 +35,6 @@ public enum FrozenPublicEnum {
case two(Int)
}
package enum PkgEnum {
case one
case two(Int)
}
public struct PublicStruct {
public var publicVar: Int
}
package enum PkgEnumWithPublicCase {
case one
case two(PublicStruct)
}
package enum PkgEnumWithExistentialCase {
case one
case two(any StringProtocol)
}
@usableFromInline
package enum UfiPkgEnum {
case one
case two(Int)
}
//--- ClientDefault.swift
import Utils
@@ -61,7 +47,16 @@ func f(_ arg: PkgEnum) -> Int {
}
}
public func g(_ arg: PublicEnum) -> Int {
func g(_ arg: UfiPkgEnum) -> Int {
switch arg { // expected-warning {{switch covers known cases, but 'UfiPkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
case .one:
return 1
case .two(let val):
return 2 + val
}
}
public func h(_ arg: PublicEnum) -> Int {
switch arg { // expected-warning {{switch covers known cases, but 'PublicEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
case .one:
return 1
@@ -70,7 +65,7 @@ public func g(_ arg: PublicEnum) -> Int {
}
}
public func h(_ arg: FrozenPublicEnum) -> Int {
public func k(_ arg: FrozenPublicEnum) -> Int {
switch arg { // no-warning
case .one:
return 1
@@ -92,8 +87,19 @@ func f(_ arg: PkgEnum) -> Int {
}
}
// Warning still shows up for usableFromInline package enum as the optimization is targeted for
// decls with package access, not the elevated public access. This might be allowed later.
func g(_ arg: UfiPkgEnum) -> Int {
switch arg { // expected-warning {{switch covers known cases, but 'UfiPkgEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
case .one:
return 1
case .two(let val):
return 2 + val
}
}
// Warning still shows up for public enum as the optimization is targeted for package types.
public func g(_ arg: PublicEnum) -> Int {
public func h(_ arg: PublicEnum) -> Int {
switch arg { // expected-warning {{switch covers known cases, but 'PublicEnum' may have additional unknown values}} {{none}} expected-note {{handle unknown values using "@unknown default"}}
case .one:
return 1
@@ -102,7 +108,7 @@ public func g(_ arg: PublicEnum) -> Int {
}
}
public func h(_ arg: FrozenPublicEnum) -> Int {
public func k(_ arg: FrozenPublicEnum) -> Int {
switch arg { // no-warning
case .one:
return 1