Skip to content

Commit fcc77a6

Browse files
Merge pull request #39032 from adrian-prantl/79462915-5.5
Disable resilience for modules imported by the MemoryBuffer loader.
2 parents 7e7333e + e754f5a commit fcc77a6

File tree

6 files changed

+48
-19
lines changed

6 files changed

+48
-19
lines changed

include/swift/AST/Module.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ class ModuleDecl
257257

258258
AccessNotesFile accessNotes;
259259

260+
/// Used by the debugger to bypass resilient access to fields.
261+
bool BypassResilience = false;
262+
260263
ModuleDecl(Identifier name, ASTContext &ctx, ImplicitImportInfo importInfo);
261264

262265
public:
@@ -290,6 +293,12 @@ class ModuleDecl
290293
AccessNotesFile &getAccessNotes() { return accessNotes; }
291294
const AccessNotesFile &getAccessNotes() const { return accessNotes; }
292295

296+
/// Return whether the module was imported with resilience disabled. The
297+
/// debugger does this to access private fields.
298+
bool getBypassResilience() const { return BypassResilience; }
299+
/// Only to be called by MemoryBufferSerializedModuleLoader.
300+
void setBypassResilience() { BypassResilience = true; }
301+
293302
ArrayRef<FileUnit *> getFiles() {
294303
assert(!Files.empty() || failedToLoad());
295304
return Files;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,11 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
261261
MemoryBufferSerializedModuleLoader(ASTContext &ctx,
262262
DependencyTracker *tracker,
263263
ModuleLoadingMode loadMode,
264-
bool IgnoreSwiftSourceInfo)
264+
bool IgnoreSwiftSourceInfo,
265+
bool BypassResilience)
265266
: SerializedModuleLoaderBase(ctx, tracker, loadMode,
266-
IgnoreSwiftSourceInfo) {}
267+
IgnoreSwiftSourceInfo),
268+
BypassResilience(BypassResilience) {}
267269

268270
std::error_code findModuleFilesInDirectory(
269271
ImportPath::Element ModuleID,
@@ -279,6 +281,7 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
279281
StringRef moduleName,
280282
const SerializedModuleBaseName &BaseName) override;
281283

284+
bool BypassResilience;
282285
public:
283286
virtual ~MemoryBufferSerializedModuleLoader();
284287

@@ -308,10 +311,10 @@ class MemoryBufferSerializedModuleLoader : public SerializedModuleLoaderBase {
308311
static std::unique_ptr<MemoryBufferSerializedModuleLoader>
309312
create(ASTContext &ctx, DependencyTracker *tracker = nullptr,
310313
ModuleLoadingMode loadMode = ModuleLoadingMode::PreferSerialized,
311-
bool IgnoreSwiftSourceInfo = false) {
314+
bool IgnoreSwiftSourceInfo = false, bool BypassResilience = false) {
312315
return std::unique_ptr<MemoryBufferSerializedModuleLoader>{
313-
new MemoryBufferSerializedModuleLoader(ctx, tracker, loadMode,
314-
IgnoreSwiftSourceInfo)};
316+
new MemoryBufferSerializedModuleLoader(
317+
ctx, tracker, loadMode, IgnoreSwiftSourceInfo, BypassResilience)};
315318
}
316319
};
317320

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,7 @@ static bool isDirectToStorageAccess(const DeclContext *UseDC,
19161916
// If the storage is resilient, we cannot access it directly at all.
19171917
if (var->isResilient(UseDC->getParentModule(),
19181918
UseDC->getResilienceExpansion()))
1919-
return false;
1919+
return var->getModuleContext()->getBypassResilience();
19201920

19211921
if (isa<ConstructorDecl>(AFD) || isa<DestructorDecl>(AFD)) {
19221922
// The access must also be a member access on 'self' in all language modes.

lib/IRGen/GenDecl.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4982,7 +4982,10 @@ llvm::Constant *IRGenModule::getAddrOfGlobalUTF16String(StringRef utf8) {
49824982
/// - For enums, new cases can be added
49834983
/// - For classes, the superclass might change the size or number
49844984
/// of stored properties
4985-
bool IRGenModule::isResilient(NominalTypeDecl *D, ResilienceExpansion expansion) {
4985+
bool IRGenModule::isResilient(NominalTypeDecl *D,
4986+
ResilienceExpansion expansion) {
4987+
if (D->getModuleContext()->getBypassResilience())
4988+
return false;
49864989
if (expansion == ResilienceExpansion::Maximal &&
49874990
Types.getLoweringMode() == TypeConverter::Mode::CompletelyFragile) {
49884991
return false;

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ static bool isArchetypeValidInFunction(ArchetypeType *A, const SILFunction *F) {
104104

105105
namespace {
106106

107+
/// When resilience is bypassed, direct access is legal, but the decls are still
108+
/// resilient.
109+
template <typename DeclType>
110+
bool checkResilience(DeclType *D, ModuleDecl *M,
111+
ResilienceExpansion expansion) {
112+
return !D->getModuleContext()->getBypassResilience() &&
113+
D->isResilient(M, expansion);
114+
}
115+
107116
/// Metaprogramming-friendly base class.
108117
template <class Impl>
109118
class SILVerifierBase : public SILInstructionVisitor<Impl> {
@@ -234,7 +243,7 @@ void verifyKeyPathComponent(SILModule &M,
234243
"property decl should be a member of the base with the same type "
235244
"as the component");
236245
require(property->hasStorage(), "property must be stored");
237-
require(!property->isResilient(M.getSwiftModule(), expansion),
246+
require(!checkResilience(property, M.getSwiftModule(), expansion),
238247
"cannot access storage of resilient property");
239248
auto propertyTy =
240249
loweredBaseTy.getFieldType(property, M, typeExpansionContext);
@@ -2045,7 +2054,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
20452054
void checkAllocGlobalInst(AllocGlobalInst *AGI) {
20462055
SILGlobalVariable *RefG = AGI->getReferencedGlobal();
20472056
if (auto *VD = RefG->getDecl()) {
2048-
require(!VD->isResilient(F.getModule().getSwiftModule(),
2057+
require(!checkResilience(VD, F.getModule().getSwiftModule(),
20492058
F.getResilienceExpansion()),
20502059
"cannot access storage of resilient global");
20512060
}
@@ -2064,7 +2073,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
20642073
RefG->getLoweredTypeInContext(F.getTypeExpansionContext()),
20652074
"global_addr/value must be the type of the variable it references");
20662075
if (auto *VD = RefG->getDecl()) {
2067-
require(!VD->isResilient(F.getModule().getSwiftModule(),
2076+
require(!checkResilience(VD, F.getModule().getSwiftModule(),
20682077
F.getResilienceExpansion()),
20692078
"cannot access storage of resilient global");
20702079
}
@@ -2752,8 +2761,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
27522761
require(!structDecl->hasUnreferenceableStorage(),
27532762
"Cannot build a struct with unreferenceable storage from elements "
27542763
"using StructInst");
2755-
require(!structDecl->isResilient(F.getModule().getSwiftModule(),
2756-
F.getResilienceExpansion()),
2764+
require(!checkResilience(structDecl, F.getModule().getSwiftModule(),
2765+
F.getResilienceExpansion()),
27572766
"cannot access storage of resilient struct");
27582767
require(SI->getType().isObject(),
27592768
"StructInst must produce an object");
@@ -2954,8 +2963,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
29542963
require(cd, "Operand of dealloc_ref must be of class type");
29552964

29562965
if (!DI->canAllocOnStack()) {
2957-
require(!cd->isResilient(F.getModule().getSwiftModule(),
2958-
F.getResilienceExpansion()),
2966+
require(!checkResilience(cd, F.getModule().getSwiftModule(),
2967+
F.getResilienceExpansion()),
29592968
"cannot directly deallocate resilient class");
29602969
}
29612970
}
@@ -3071,7 +3080,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
30713080
"result of struct_extract cannot be address");
30723081
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
30733082
require(sd, "must struct_extract from struct");
3074-
require(!sd->isResilient(F.getModule().getSwiftModule(),
3083+
require(!checkResilience(sd, F.getModule().getSwiftModule(),
30753084
F.getResilienceExpansion()),
30763085
"cannot access storage of resilient struct");
30773086
require(!EI->getField()->isStatic(),
@@ -3120,7 +3129,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
31203129
"must derive struct_element_addr from address");
31213130
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
31223131
require(sd, "struct_element_addr operand must be struct address");
3123-
require(!sd->isResilient(F.getModule().getSwiftModule(),
3132+
require(!checkResilience(sd, F.getModule().getSwiftModule(),
31243133
F.getResilienceExpansion()),
31253134
"cannot access storage of resilient struct");
31263135
require(EI->getType().isAddress(),
@@ -3153,7 +3162,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
31533162
SILType operandTy = EI->getOperand()->getType();
31543163
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
31553164
require(cd, "ref_element_addr operand must be a class instance");
3156-
require(!cd->isResilient(F.getModule().getSwiftModule(),
3165+
require(!checkResilience(cd, F.getModule().getSwiftModule(),
31573166
F.getResilienceExpansion()),
31583167
"cannot access storage of resilient class");
31593168

@@ -3177,7 +3186,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
31773186
SILType operandTy = RTAI->getOperand()->getType();
31783187
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
31793188
require(cd, "ref_tail_addr operand must be a class instance");
3180-
require(!cd->isResilient(F.getModule().getSwiftModule(),
3189+
require(!checkResilience(cd, F.getModule().getSwiftModule(),
31813190
F.getResilienceExpansion()),
31823191
"cannot access storage of resilient class");
31833192
require(cd, "ref_tail_addr operand must be a class instance");
@@ -3187,7 +3196,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
31873196
SILType operandTy = DSI->getOperand()->getType();
31883197
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
31893198
require(sd, "must struct_extract from struct");
3190-
require(!sd->isResilient(F.getModule().getSwiftModule(),
3199+
require(!checkResilience(sd, F.getModule().getSwiftModule(),
31913200
F.getResilienceExpansion()),
31923201
"cannot access storage of resilient struct");
31933202
if (F.hasOwnership()) {

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,11 @@ MemoryBufferSerializedModuleLoader::loadModule(SourceLoc importLoc,
12341234
if (!file)
12351235
return nullptr;
12361236

1237+
// The MemoryBuffer loader is used by LLDB during debugging. Modules imported
1238+
// from .swift_ast sections are never produced from textual interfaces. By
1239+
// disabling resilience the debugger can directly access private members.
1240+
if (BypassResilience)
1241+
M->setBypassResilience();
12371242
M->addFile(*file);
12381243
Ctx.addLoadedModule(M);
12391244
return M;

0 commit comments

Comments
 (0)