Skip to content

Commit 162794c

Browse files
committed
SIL: don't set the let flag on a SILGlobalVariable if it contains a struct with @_rawLayout
Even if the global declaration is a `let`. Raw-layout storage may be mutated even for let-variables. Treating such variables as non-let ensures that optimization don't assume that they are not mutated.
1 parent 5076fec commit 162794c

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage,
4343
return var;
4444
}
4545

46+
static bool isGlobalLet(SILModule &mod, VarDecl *decl, SILType type) {
47+
if (!decl)
48+
return false;
49+
50+
if (!decl->isLet())
51+
return false;
52+
53+
// Raw-layout storage may be mutated even for let-variables. Therefore don't
54+
// treat such variables as `let` in SIL.
55+
auto teCtxt = TypeExpansionContext::maximal(mod.getSwiftModule(),
56+
mod.isWholeModule());
57+
auto typeProps = mod.Types.getTypeProperties(type, teCtxt);
58+
if (typeProps.isOrContainsRawLayout())
59+
return false;
60+
61+
return true;
62+
}
63+
4664
SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
4765
SerializedKind_t serializedKind,
4866
StringRef Name, SILType LoweredType,
@@ -53,7 +71,7 @@ SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
5371
Linkage(unsigned(Linkage)), HasLocation(Loc.has_value()), VDecl(Decl) {
5472
setSerializedKind(serializedKind);
5573
IsDeclaration = isAvailableExternally(Linkage);
56-
setLet(Decl ? Decl->isLet() : false);
74+
setLet(isGlobalLet(Module, Decl, LoweredType));
5775
Module.silGlobals.push_back(this);
5876
}
5977

0 commit comments

Comments
 (0)