Serialization: restrict swiftmodules to distribution channels

There are scenarios where different compilers are distributed with
compatible serialization format versions and the same tag. Distinguish
swiftmodules in such a case by assigning them to different distribution
channels. A compiler expecting a specific channel will only read
swiftmodules from the same channel. The channels should be defined by
downstream code as it is by definition vendor specific.

For development, a no-channel compiler loads or defining the env var
SWIFT_IGNORE_SWIFTMODULE_REVISION skips this new check.

rdar://123731777
This commit is contained in:
Alexis Laferrière
2024-02-29 17:48:34 -08:00
parent ffc2d9f9a7
commit 1e4fe67f40
10 changed files with 149 additions and 1 deletions

View File

@@ -418,6 +418,21 @@ static ValidationInfo validateControlBlock(
}
break;
}
case control_block::CHANNEL: {
static const char* ignoreRevision =
::getenv("SWIFT_IGNORE_SWIFTMODULE_REVISION");
if (ignoreRevision)
break;
StringRef moduleChannel = blobData,
compilerChannel = version::getCurrentCompilerChannel();
if (requiresRevisionMatch && !compilerChannel.empty() &&
moduleChannel != compilerChannel) {
result.problematicChannel = moduleChannel;
result.status = Status::ChannelIncompatible;
}
break;
}
case control_block::IS_OSSA: {
auto isModuleInOSSA = scratch[0];
if (requiresOSSAModules && !isModuleInOSSA)
@@ -532,6 +547,7 @@ std::string serialization::StatusToString(Status S) {
case Status::FormatTooOld: return "FormatTooOld";
case Status::FormatTooNew: return "FormatTooNew";
case Status::RevisionIncompatible: return "RevisionIncompatible";
case Status::ChannelIncompatible: return "ChannelIncompatible";
case Status::NotInOSSA: return "NotInOSSA";
case Status::NoncopyableGenericsMismatch:
return "NoncopyableGenericsMismatch";