mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Serialization] Fix deserializing opaque types for computed properties and subscripts
A client shouldn't know about the underlying type of an opaque type unless it can see the body of the naming decl. Attempting to read it can lead to accessing a hidden dependency and a compiler crash. This was protected by a check specific to function decls but var decls and subscripts were not handled. To support them we have to move this logic to the writer side where we have access to the full AbstractStorageDecl and write in the swifmodule whether the underlying type should be visible outside of the module. rdar://117607906
This commit is contained in:
@@ -4221,11 +4221,13 @@ public:
|
||||
GenericSignatureID genericSigID;
|
||||
SubstitutionMapID underlyingTypeSubsID;
|
||||
uint8_t rawAccessLevel;
|
||||
bool exportUnderlyingType;
|
||||
decls_block::OpaqueTypeLayout::readRecord(scratch, contextID,
|
||||
namingDeclID, interfaceSigID,
|
||||
interfaceTypeID, genericSigID,
|
||||
underlyingTypeSubsID,
|
||||
rawAccessLevel);
|
||||
rawAccessLevel,
|
||||
exportUnderlyingType);
|
||||
|
||||
auto declContext = MF.getDeclContext(contextID);
|
||||
auto interfaceSigOrErr = MF.getGenericSignatureChecked(interfaceSigID);
|
||||
@@ -4261,16 +4263,25 @@ public:
|
||||
else
|
||||
opaqueDecl->setGenericSignature(GenericSignature());
|
||||
|
||||
auto *AFD = dyn_cast<AbstractFunctionDecl>(namingDecl);
|
||||
if (MF.getResilienceStrategy() == ResilienceStrategy::Resilient &&
|
||||
!MF.FileContext->getParentModule()->isMainModule() &&
|
||||
AFD && AFD->getResilienceExpansion() != ResilienceExpansion::Minimal) {
|
||||
if (!MF.FileContext->getParentModule()->isMainModule() &&
|
||||
!exportUnderlyingType) {
|
||||
// Do not try to read the underlying type information if the function
|
||||
// is not inlinable in clients. This reflects the swiftinterface behavior
|
||||
// in where clients are only aware of the underlying type when the body
|
||||
// of the function is public.
|
||||
LLVM_DEBUG(
|
||||
llvm::dbgs() << "Ignoring underlying information for opaque type of '";
|
||||
llvm::dbgs() << namingDecl->getName();
|
||||
llvm::dbgs() << "'\n";
|
||||
);
|
||||
|
||||
} else if (underlyingTypeSubsID) {
|
||||
LLVM_DEBUG(
|
||||
llvm::dbgs() << "Loading underlying information for opaque type of '";
|
||||
llvm::dbgs() << namingDecl->getName();
|
||||
llvm::dbgs() << "'\n";
|
||||
);
|
||||
|
||||
auto subMapOrError = MF.getSubstitutionMapChecked(underlyingTypeSubsID);
|
||||
if (!subMapOrError) {
|
||||
// If the underlying type references internal details, ignore it.
|
||||
|
||||
Reference in New Issue
Block a user