Skip to content

Commit afbc4a5

Browse files
authored
Merge pull request #62251 from nkcsgexi/allowable-serialization
serialization: encode allowable client names in binary module format
2 parents 6d2a3bb + 29504bd commit afbc4a5

19 files changed

+115
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,10 @@ WARNING(module_not_compiled_with_library_evolution,none,
984984
"using it means binary compatibility for %1 can't be guaranteed",
985985
(Identifier, Identifier))
986986

987+
ERROR(module_allowable_client_violation,none,
988+
"module %0 doesn't allow importation from module %1",
989+
(Identifier, Identifier))
990+
987991
REMARK(cross_import_added,none,
988992
"import of %0 and %1 triggered a cross-import of %2",
989993
(Identifier, Identifier, Identifier))

include/swift/AST/Module.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,19 @@ class ModuleDecl
418418
return UserModuleVersion;
419419
}
420420

421+
void addAllowableClientName(Identifier name) {
422+
allowableClientNames.push_back(name);
423+
}
424+
ArrayRef<Identifier> getAllowableClientNames() const {
425+
return allowableClientNames;
426+
}
427+
bool allowImportedBy(ModuleDecl *importer) const;
421428
private:
429+
430+
/// An array of module names that are allowed to import this one.
431+
/// Any module can import this one if empty.
432+
std::vector<Identifier> allowableClientNames;
433+
422434
/// A cache of this module's underlying module and required bystander if it's
423435
/// an underscored cross-import overlay.
424436
Optional<std::pair<ModuleDecl *, Identifier>> declaringModuleAndBystander;

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class FrontendOptions {
9797
/// User-defined module version number.
9898
llvm::VersionTuple UserModuleVersion;
9999

100+
/// A set of modules allowed to import this module.
101+
std::set<std::string> AllowableClients;
102+
100103
/// Emit index data for imported serialized swift system modules.
101104
bool IndexSystemModules = false;
102105

include/swift/Serialization/SerializationOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace swift {
3535
std::string ABIDescriptorPath;
3636
bool emptyABIDescriptor = false;
3737
llvm::VersionTuple UserModuleVersion;
38+
std::set<std::string> AllowableClients;
3839
std::string SDKName;
3940

4041
StringRef GroupInfoPath;

include/swift/Serialization/Validation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct ValidationInfo {
9393
StringRef sdkName = {};
9494
size_t bytes = 0;
9595
Status status = Status::Malformed;
96+
std::vector<StringRef> allowableClients;
9697
};
9798

9899
/// A collection of options that can be used to set up a new AST context

lib/AST/Module.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,18 @@ Identifier ModuleDecl::getRealName() const {
19231923
return getASTContext().getRealModuleName(getName());
19241924
}
19251925

1926+
bool ModuleDecl::allowImportedBy(ModuleDecl *importer) const {
1927+
if (allowableClientNames.empty())
1928+
return true;
1929+
for (auto id: allowableClientNames) {
1930+
if (importer->getRealName() == id)
1931+
return true;
1932+
if (importer->getABIName() == id)
1933+
return true;
1934+
}
1935+
return false;
1936+
}
1937+
19261938
Identifier ModuleDecl::getABIName() const {
19271939
if (!ModuleABIName.empty())
19281940
return ModuleABIName;

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ bool ArgsToFrontendOptionsConverter::convert(
120120
}
121121
}
122122

123+
for (auto A : Args.getAllArgValues(options::OPT_allowable_client)) {
124+
Opts.AllowableClients.insert(StringRef(A).str());
125+
}
126+
123127
Opts.DisableImplicitModules |= Args.hasArg(OPT_disable_implicit_swift_modules);
124128

125129
Opts.ImportPrescan |= Args.hasArg(OPT_import_prescan);

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
154154
serializationOpts.ImportedHeader = opts.ImplicitObjCHeaderPath;
155155
serializationOpts.ModuleLinkName = opts.ModuleLinkName;
156156
serializationOpts.UserModuleVersion = opts.UserModuleVersion;
157+
serializationOpts.AllowableClients = opts.AllowableClients;
157158

158159
serializationOpts.PublicDependentLibraries =
159160
getIRGenOptions().PublicLinkLibraries;

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
266266
SerializationOpts.AutolinkForceLoad =
267267
!Invocation.getIRGenOptions().ForceLoadSymbolName.empty();
268268
SerializationOpts.UserModuleVersion = FEOpts.UserModuleVersion;
269+
SerializationOpts.AllowableClients = FEOpts.AllowableClients;
269270

270271
// Record any non-SDK module interface files for the debug info.
271272
StringRef SDKPath = Instance.getASTContext().SearchPathOpts.getSDKPath();

lib/Sema/ImportResolution.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ struct UnboundImport {
137137
void validateTestable(ModuleDecl *topLevelModule);
138138
void validateResilience(NullablePtr<ModuleDecl> topLevelModule,
139139
SourceFile &SF);
140+
void validateAllowableClient(ModuleDecl *topLevelModule, SourceFile &SF);
140141

141142
/// Diagnoses an inability to import \p modulePath in this situation and, if
142143
/// \p attrs is provided and has an \p attrKind, invalidates the attribute and
@@ -621,6 +622,7 @@ void UnboundImport::validateOptions(NullablePtr<ModuleDecl> topLevelModule,
621622
// changing behavior, but it smells funny.
622623
validateTestable(top);
623624
validatePrivate(top);
625+
validateAllowableClient(top, SF);
624626
}
625627

626628
validateResilience(topLevelModule, SF);
@@ -712,6 +714,19 @@ void UnboundImport::validateTestable(ModuleDecl *topLevelModule) {
712714
diagnoseInvalidAttr(DAK_Testable, ctx.Diags, diag::module_not_testable);
713715
}
714716

717+
void UnboundImport::validateAllowableClient(ModuleDecl *importee,
718+
SourceFile &SF) {
719+
assert(importee);
720+
auto *importer = SF.getParentModule();
721+
if (!importee->allowImportedBy(importer)) {
722+
ASTContext &ctx = SF.getASTContext();
723+
ctx.Diags.diagnose(import.module.getModulePath().front().Loc,
724+
diag::module_allowable_client_violation,
725+
importee->getName(),
726+
importer->getName());
727+
}
728+
}
729+
715730
void UnboundImport::validateResilience(NullablePtr<ModuleDecl> topLevelModule,
716731
SourceFile &SF) {
717732
if (import.options.contains(ImportFlags::ImplementationOnly))

0 commit comments

Comments
 (0)