Skip to content

Commit d593442

Browse files
committed
Add module trace information for strict memory safety
Extend the module trace format with a field indicating whether a given module, or any module it depends on, was compiled with strict memory safety enabled. This separate output from the compiler can be used as part of an audit to determine what parts of Swift programs are built with strict memory safety checking enabled.
1 parent 92fbedc commit d593442

File tree

15 files changed

+85
-8
lines changed

15 files changed

+85
-8
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
726726
HasAnyUnavailableDuringLoweringValues : 1
727727
);
728728

729-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
729+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8,
730730
/// If the module is compiled as static library.
731731
StaticLibrary : 1,
732732

@@ -792,7 +792,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
792792
AllowNonResilientAccess : 1,
793793

794794
/// Whether this module has been built with -package-cmo.
795-
SerializePackageEnabled : 1
795+
SerializePackageEnabled : 1,
796+
797+
/// Whether this module has enabled strict memory safety checking.
798+
StrictMemorySafety : 1
796799
);
797800

798801
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,

include/swift/AST/Module.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,15 @@ class ModuleDecl
830830
Bits.ModuleDecl.IsConcurrencyChecked = value;
831831
}
832832

833+
/// Whether this module has enable strict memory safety checking.
834+
bool strictMemorySafety() const {
835+
return Bits.ModuleDecl.StrictMemorySafety;
836+
}
837+
838+
void setStrictMemorySafety(bool value = true) {
839+
Bits.ModuleDecl.StrictMemorySafety = value;
840+
}
841+
833842
bool isObjCNameLookupCachePopulated() const {
834843
return Bits.ModuleDecl.ObjCNameLookupCachePopulated;
835844
}

include/swift/Serialization/Validation.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class ExtendedValidationInfo {
149149
unsigned HasCxxInteroperability : 1;
150150
unsigned AllowNonResilientAccess: 1;
151151
unsigned SerializePackageEnabled: 1;
152+
unsigned StrictMemorySafety: 1;
152153
} Bits;
153154
public:
154155
ExtendedValidationInfo() : Bits() {}
@@ -246,6 +247,13 @@ class ExtendedValidationInfo {
246247
void setIsConcurrencyChecked(bool val = true) {
247248
Bits.IsConcurrencyChecked = val;
248249
}
250+
bool strictMemorySafety() const {
251+
return Bits.StrictMemorySafety;
252+
}
253+
void setStrictMemorySafety(bool val = true) {
254+
Bits.StrictMemorySafety = val;
255+
}
256+
249257
bool hasCxxInteroperability() const { return Bits.HasCxxInteroperability; }
250258
void setHasCxxInteroperability(bool val) {
251259
Bits.HasCxxInteroperability = val;

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
781781
Bits.ModuleDecl.CXXStdlibKind = 0;
782782
Bits.ModuleDecl.AllowNonResilientAccess = 0;
783783
Bits.ModuleDecl.SerializePackageEnabled = 0;
784+
Bits.ModuleDecl.StrictMemorySafety = 0;
784785

785786
// Populate the module's files.
786787
SmallVector<FileUnit *, 2> files;

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,8 @@ ModuleDecl *CompilerInstance::getMainModule() const {
14971497
MainModule->setAllowNonResilientAccess();
14981498
if (Invocation.getSILOptions().EnableSerializePackage)
14991499
MainModule->setSerializePackageEnabled();
1500+
if (Invocation.getLangOptions().hasFeature(Feature::WarnUnsafe))
1501+
MainModule->setStrictMemorySafety(true);
15001502

15011503
if (!Invocation.getFrontendOptions()
15021504
.SwiftInterfaceCompilerVersion.empty()) {

lib/FrontendTool/LoadedModuleTrace.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct SwiftModuleTraceInfo {
5353
std::string Path;
5454
bool IsImportedDirectly;
5555
bool SupportsLibraryEvolution;
56+
bool StrictMemorySafety;
5657
};
5758

5859
struct SwiftMacroTraceInfo {
@@ -65,6 +66,7 @@ struct LoadedModuleTraceFormat {
6566
unsigned Version;
6667
Identifier Name;
6768
std::string Arch;
69+
bool StrictMemorySafety;
6870
std::vector<SwiftModuleTraceInfo> SwiftModules;
6971
std::vector<SwiftMacroTraceInfo> SwiftMacros;
7072
};
@@ -80,6 +82,8 @@ template <> struct ObjectTraits<SwiftModuleTraceInfo> {
8082
out.mapRequired("isImportedDirectly", contents.IsImportedDirectly);
8183
out.mapRequired("supportsLibraryEvolution",
8284
contents.SupportsLibraryEvolution);
85+
out.mapRequired("strictMemorySafety",
86+
contents.StrictMemorySafety);
8387
}
8488
};
8589

@@ -104,6 +108,8 @@ template <> struct ObjectTraits<LoadedModuleTraceFormat> {
104108

105109
out.mapRequired("arch", contents.Arch);
106110

111+
out.mapRequired("strictMemorySafety", contents.StrictMemorySafety);
112+
107113
// The 'swiftmodules' key is kept for backwards compatibility.
108114
std::vector<std::string> moduleNames;
109115
for (auto &m : contents.SwiftModules)
@@ -643,7 +649,8 @@ static void computeSwiftModuleTraceInfo(
643649
/*IsImportedDirectly=*/
644650
isImportedDirectly,
645651
/*SupportsLibraryEvolution=*/
646-
depMod->isResilient()});
652+
depMod->isResilient(),
653+
depMod->strictMemorySafety()});
647654
buffer.clear();
648655

649656
continue;
@@ -782,8 +789,9 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
782789
LoadedModuleTraceFormat trace = {
783790
/*version=*/LoadedModuleTraceFormat::CurrentVersion,
784791
/*name=*/mainModule->getName(),
785-
/*arch=*/ctxt.LangOpts.Target.getArchName().str(), swiftModules,
786-
swiftMacros};
792+
/*arch=*/ctxt.LangOpts.Target.getArchName().str(),
793+
mainModule ? mainModule->strictMemorySafety() : false,
794+
swiftModules, swiftMacros};
787795

788796
// raw_fd_ostream is unbuffered, and we may have multiple processes writing,
789797
// so first write to memory and then dump the buffer to the trace file.

lib/Serialization/ModuleFile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,9 @@ class ModuleFile
704704
/// \c true if this module was built with complete checking for concurrency.
705705
bool isConcurrencyChecked() const { return Core->isConcurrencyChecked(); }
706706

707+
/// \c true if this module was built with strict memory safety.
708+
bool strictMemorySafety() const { return Core->strictMemorySafety(); }
709+
707710
/// Associates this module file with the AST node representing it.
708711
///
709712
/// Checks that the file is compatible with the AST module it's being loaded

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
221221
case options_block::SWIFT_INTERFACE_COMPILER_VERSION:
222222
extendedInfo.setSwiftInterfaceCompilerVersion(blobData);
223223
break;
224+
case options_block::STRICT_MEMORY_SAFETY:
225+
extendedInfo.setStrictMemorySafety(true);
226+
break;
224227
default:
225228
// Unknown options record, possibly for use by a future version of the
226229
// module format.
@@ -1497,6 +1500,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
14971500
Bits.CXXStdlibKind = static_cast<uint8_t>(extInfo.getCXXStdlibKind());
14981501
Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess();
14991502
Bits.SerializePackageEnabled = extInfo.serializePackageEnabled();
1503+
Bits.StrictMemorySafety = extInfo.strictMemorySafety();
15001504
MiscVersion = info.miscVersion;
15011505
SDKVersion = info.sdkVersion;
15021506
ModuleABIName = extInfo.getModuleABIName();

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,11 @@ class ModuleFileSharedCore {
415415
/// Whether this module is built with -package-cmo.
416416
unsigned SerializePackageEnabled : 1;
417417

418+
/// Whether this module enabled strict memory safety.
419+
unsigned StrictMemorySafety : 1;
420+
418421
// Explicitly pad out to the next word boundary.
419-
unsigned : 3;
422+
unsigned : 2;
420423
} Bits = {};
421424
static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small");
422425

@@ -667,6 +670,8 @@ class ModuleFileSharedCore {
667670

668671
bool isConcurrencyChecked() const { return Bits.IsConcurrencyChecked; }
669672

673+
bool strictMemorySafety() const { return Bits.StrictMemorySafety; }
674+
670675
/// How should \p dependency be loaded for a transitive import via \c this?
671676
///
672677
/// If \p importNonPublicDependencies, more transitive dependencies

lib/Serialization/ModuleFormat.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ namespace options_block {
970970
CXX_STDLIB_KIND,
971971
PUBLIC_MODULE_NAME,
972972
SWIFT_INTERFACE_COMPILER_VERSION,
973+
STRICT_MEMORY_SAFETY,
973974
};
974975

975976
using SDKPathLayout = BCRecordLayout<
@@ -1066,12 +1067,16 @@ namespace options_block {
10661067
SERIALIZE_PACKAGE_ENABLED
10671068
>;
10681069

1070+
using StrictMemorySafetyLayout = BCRecordLayout<
1071+
STRICT_MEMORY_SAFETY
1072+
>;
1073+
10691074
using PublicModuleNameLayout = BCRecordLayout<
10701075
PUBLIC_MODULE_NAME,
10711076
BCBlob
10721077
>;
10731078

1074-
using SwiftInterfaceCompilerVersionLayout = BCRecordLayout<
1079+
using SwiftInterfaceCompilerVersionLayout = BCRecordLayout<
10751080
SWIFT_INTERFACE_COMPILER_VERSION,
10761081
BCBlob // version tuple
10771082
>;

0 commit comments

Comments
 (0)