Skip to content

Commit 4348515

Browse files
authored
Merge pull request #71899 from apple/es-check-exp
Make module opt in to allow non-resilient access for in-package resilience bypass.
2 parents 5a42260 + 8ffd8ef commit 4348515

19 files changed

+158
-15
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
694694
HasAnyUnavailableDuringLoweringValues : 1
695695
);
696696

697-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
697+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1,
698698
/// If the module is compiled as static library.
699699
StaticLibrary : 1,
700700

@@ -750,7 +750,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
750750
ObjCNameLookupCachePopulated : 1,
751751

752752
/// Whether this module has been built with C++ interoperability enabled.
753-
HasCxxInteroperability : 1
753+
HasCxxInteroperability : 1,
754+
755+
/// Whether this module has been built with -experimental-allow-non-resilient-access.
756+
AllowNonResilientAccess : 1
754757
);
755758

756759
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,
@@ -2931,9 +2934,9 @@ class ValueDecl : public Decl {
29312934
/// if the base declaration is \c open, the override might have to be too.
29322935
bool hasOpenAccess(const DeclContext *useDC) const;
29332936

2934-
/// True if opted in for bypassing resilience within a package. Allowed only on
2935-
/// access from the \p accessingModule to a package decl in the defining
2936-
/// binary (not interface) module within the same package.
2937+
/// True if opted in to bypass a resilience check at the use site in the
2938+
/// \p accessingModule that references decls defined in a module
2939+
/// that allows non-resilient access within the same package.
29372940
bool bypassResilienceInPackage(ModuleDecl *accessingModule) const;
29382941

29392942
/// FIXME: This is deprecated.

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ WARNING(emit_reference_dependencies_without_primary_file,none,
168168

169169
WARNING(ignoring_option_requires_option,none,
170170
"ignoring %0 (requires %1)", (StringRef, StringRef))
171+
WARNING(warn_ignore_option_overriden_by,none,
172+
"ignoring %0 (overriden by %1)", (StringRef, StringRef))
171173

172174
WARNING(warn_implicit_concurrency_import_failed,none,
173175
"unable to perform implicit import of \"_Concurrency\" module: no such module found", ())

include/swift/AST/Module.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,16 @@ class ModuleDecl
711711
Bits.ModuleDecl.IsBuiltFromInterface = flag;
712712
}
713713

714+
/// Returns true if -experimental-allow-non-resilient-access was passed
715+
/// and the module is built from source.
716+
bool allowNonResilientAccess() const {
717+
return Bits.ModuleDecl.AllowNonResilientAccess &&
718+
!Bits.ModuleDecl.IsBuiltFromInterface;
719+
}
720+
void setAllowNonResilientAccess(bool flag = true) {
721+
Bits.ModuleDecl.AllowNonResilientAccess = flag;
722+
}
723+
714724
/// Returns true if this module is a non-Swift module that was imported into
715725
/// Swift.
716726
///

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@ class FrontendOptions {
311311
/// Should we skip decls that cannot be referenced externally?
312312
bool SkipNonExportableDecls = false;
313313

314+
/// True if -experimental-allow-non-resilient-access is passed and built
315+
/// from source.
316+
bool AllowNonResilientAccess = false;
317+
314318
/// Should we warn if an imported module needed to be rebuilt from a
315319
/// module interface file?
316320
bool RemarkOnRebuildFromModuleInterface = false;

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ def experimental_package_bypass_resilience : Flag<["-"], "experimental-package-b
524524
Flags<[FrontendOption]>,
525525
HelpText<"Enable optimization to bypass resilience within a package">;
526526

527+
def experimental_allow_non_resilient_access : Flag<["-"], "experimental-allow-non-resilient-access">,
528+
Flags<[FrontendOption]>,
529+
HelpText<"Allow non-resilient access by generating all contents besides exportable decls">;
530+
527531
def library_level : Separate<["-"], "library-level">,
528532
MetaVarName<"<level>">,
529533
Flags<[HelpHidden, FrontendOption, ModuleInterfaceOption]>,

include/swift/Serialization/Validation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class ExtendedValidationInfo {
144144
unsigned IsAllowModuleWithCompilerErrorsEnabled : 1;
145145
unsigned IsConcurrencyChecked : 1;
146146
unsigned HasCxxInteroperability : 1;
147+
unsigned AllowNonResilientAccess: 1;
147148
} Bits;
148149
public:
149150
ExtendedValidationInfo() : Bits() {}
@@ -208,6 +209,10 @@ class ExtendedValidationInfo {
208209
void setIsBuiltFromInterface(bool val) {
209210
Bits.IsBuiltFromInterface = val;
210211
}
212+
bool allowNonResilientAccess() const { return Bits.AllowNonResilientAccess; }
213+
void setAllowNonResilientAccess(bool val) {
214+
Bits.AllowNonResilientAccess = val;
215+
}
211216
bool isAllowModuleWithCompilerErrorsEnabled() {
212217
return Bits.IsAllowModuleWithCompilerErrorsEnabled;
213218
}

lib/AST/Decl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4214,9 +4214,13 @@ bool ValueDecl::hasOpenAccess(const DeclContext *useDC) const {
42144214
}
42154215

42164216
bool ValueDecl::bypassResilienceInPackage(ModuleDecl *accessingModule) const {
4217+
// Client needs to opt in to bypass resilience checks at the use site.
4218+
// Client and the loaded module both need to be in the same package.
4219+
// The loaded module needs to be built from source and opt in to allow
4220+
// non-resilient access.
42174221
return getASTContext().LangOpts.EnableBypassResilienceInPackage &&
42184222
getModuleContext()->inSamePackage(accessingModule) &&
4219-
!getModuleContext()->isBuiltFromInterface();
4223+
getModuleContext()->allowNonResilientAccess();
42204224
}
42214225

42224226
/// Given the formal access level for using \p VD, compute the scope where

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
722722
Bits.ModuleDecl.IsConcurrencyChecked = 0;
723723
Bits.ModuleDecl.ObjCNameLookupCachePopulated = 0;
724724
Bits.ModuleDecl.HasCxxInteroperability = 0;
725+
Bits.ModuleDecl.AllowNonResilientAccess = 0;
725726
}
726727

727728
void ModuleDecl::setIsSystemModule(bool flag) {

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,26 @@ bool ArgsToFrontendOptionsConverter::convert(
314314
"-enable-library-evolution");
315315
}
316316

317+
Opts.AllowNonResilientAccess = Args.hasArg(OPT_experimental_allow_non_resilient_access);
318+
if (Opts.AllowNonResilientAccess) {
319+
// Override the option to skip non-exportable decls.
320+
if (Opts.SkipNonExportableDecls) {
321+
Diags.diagnose(SourceLoc(), diag::warn_ignore_option_overriden_by,
322+
"-experimental-skip-non-exportable-decls",
323+
"-experimental-allow-non-resilient-access");
324+
Opts.SkipNonExportableDecls = false;
325+
}
326+
// If built from interface, non-resilient access should not be allowed.
327+
if (Opts.AllowNonResilientAccess &&
328+
(Opts.RequestedAction == FrontendOptions::ActionType::CompileModuleFromInterface ||
329+
Opts.RequestedAction == FrontendOptions::ActionType::TypecheckModuleFromInterface)) {
330+
Diags.diagnose(SourceLoc(), diag::warn_ignore_option_overriden_by,
331+
"-experimental-allow-non-resilient-access",
332+
"-compile-module-from-interface or -typecheck-module-from-interface");
333+
Opts.AllowNonResilientAccess = false;
334+
}
335+
}
336+
317337
// HACK: The driver currently erroneously passes all flags to module interface
318338
// verification jobs. -experimental-skip-non-exportable-decls is not
319339
// appropriate for verification tasks and should be ignored, though.

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,8 @@ ModuleDecl *CompilerInstance::getMainModule() const {
14021402
if (Invocation.getLangOptions().EnableCXXInterop &&
14031403
Invocation.getLangOptions().RequireCxxInteropToImportCxxInteropModule)
14041404
MainModule->setHasCxxInteroperability();
1405+
if (Invocation.getFrontendOptions().AllowNonResilientAccess)
1406+
MainModule->setAllowNonResilientAccess();
14051407

14061408
// Register the main module with the AST context.
14071409
Context->addLoadedModule(MainModule);

0 commit comments

Comments
 (0)