Skip to content

Commit 3839bf0

Browse files
authored
Merge pull request #1817 from compnerd/sanitized
SwiftDriver: enable `-sanitize=` on Windows selectively
2 parents 2b9e404 + 3cf9189 commit 3839bf0

File tree

4 files changed

+37
-44
lines changed

4 files changed

+37
-44
lines changed

Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift

+7-1
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,14 @@ extension Toolchain {
3232
if platform == "android" {
3333
platform = "linux"
3434
}
35+
36+
// NOTE(compnerd) Windows uses the per-target runtime directory for the
37+
// Windows runtimes. This should also be done for the other platforms, but
38+
// is not critical. This is done to allow for the Windows runtimes to be
39+
// co-located for all the currently supported architectures: x86, x64, arm64.
40+
let bIsWindows = targetInfo.target.triple.isWindows
3541
return VirtualPath.lookup(targetInfo.runtimeResourcePath.path)
36-
.appending(components: "clang", "lib", platform)
42+
.appending(components: "clang", "lib", bIsWindows ? targetInfo.target.triple.triple : platform)
3743
}
3844

3945
func runtimeLibraryPaths(

Sources/SwiftDriver/Jobs/WindowsToolchain+LinkerSupport.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,10 @@ extension WindowsToolchain {
223223
commandLine.appendFlag(optArg)
224224
}
225225

226-
// FIXME(compnerd) render asan/ubsan runtime link for executables
226+
if !sanitizers.isEmpty {
227+
let sanitize = sanitizers.map(\.rawValue).sorted().joined(separator: ",")
228+
commandLine.appendFlag("-fsanitize=\(sanitize)")
229+
}
227230

228231
if parsedOptions.contains(.profileGenerate) {
229232
assert(bForceLLD,

Sources/SwiftDriver/Toolchains/WindowsToolchain.swift

+5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ extension WindowsToolchain.ToolchainValidationError {
130130
public func runtimeLibraryName(for sanitizer: Sanitizer, targetTriple: Triple,
131131
isShared: Bool) throws -> String {
132132
// TODO(compnerd) handle shared linking
133+
134+
// FIXME(compnerd) when should `clang_rt.ubsan_standalone_cxx` be used?
135+
if sanitizer == .undefinedBehavior {
136+
return "clang_rt.ubsan_standalone.lib"
137+
}
133138
return "clang_rt.\(sanitizer.libraryName).lib"
134139
}
135140

Tests/SwiftDriverTests/SwiftDriverTests.swift

+21-42
Original file line numberDiff line numberDiff line change
@@ -2708,56 +2708,40 @@ final class SwiftDriverTests: XCTestCase {
27082708

27092709
func testSanitizerArgs() throws {
27102710
let commonArgs = [
2711-
"swiftc", "foo.swift", "bar.swift",
2712-
"-emit-executable", "-target", "x86_64-apple-macosx10.9",
2713-
"-module-name", "Test"
2711+
"swiftc", "foo.swift", "bar.swift", "-emit-executable", "-module-name", "Test", "-use-ld=lld"
27142712
]
2715-
// FIXME: This doesn't work on Linux.
2716-
#if os(macOS)
2713+
2714+
#if os(macOS) || os(Windows)
27172715
do {
27182716
// address sanitizer
27192717
var driver = try Driver(args: commonArgs + ["-sanitize=address"])
2720-
let plannedJobs = try driver.planBuild()
2721-
2722-
XCTAssertEqual(plannedJobs.count, 3)
2723-
2724-
let compileJob = plannedJobs[0]
2725-
let compileCmd = compileJob.commandLine
2726-
XCTAssertTrue(compileCmd.contains(.flag("-sanitize=address")))
2718+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
27272719

2728-
let linkJob = plannedJobs[2]
2729-
let linkCmd = linkJob.commandLine
2730-
XCTAssertTrue(linkCmd.contains(.flag("-fsanitize=address")))
2720+
XCTAssertEqual(jobs.count, 3)
2721+
XCTAssertJobInvocationMatches(jobs[0], .flag("-sanitize=address"))
2722+
XCTAssertJobInvocationMatches(jobs[2], .flag("-fsanitize=address"))
27312723
}
27322724

27332725
do {
27342726
// address sanitizer on a dylib
27352727
var driver = try Driver(args: commonArgs + ["-sanitize=address", "-emit-library"])
2736-
let plannedJobs = try driver.planBuild()
2737-
2738-
XCTAssertEqual(plannedJobs.count, 3)
2739-
2740-
let compileJob = plannedJobs[0]
2741-
let compileCmd = compileJob.commandLine
2742-
XCTAssertTrue(compileCmd.contains(.flag("-sanitize=address")))
2728+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
27432729

2744-
let linkJob = plannedJobs[2]
2745-
let linkCmd = linkJob.commandLine
2746-
XCTAssertTrue(linkCmd.contains(.flag("-fsanitize=address")))
2730+
XCTAssertEqual(jobs.count, 3)
2731+
XCTAssertJobInvocationMatches(jobs[0], .flag("-sanitize=address"))
2732+
XCTAssertJobInvocationMatches(jobs[2], .flag("-fsanitize=address"))
27472733
}
27482734

27492735
do {
27502736
// *no* address sanitizer on a static lib
27512737
var driver = try Driver(args: commonArgs + ["-sanitize=address", "-emit-library", "-static"])
2752-
let plannedJobs = try driver.planBuild()
2753-
2754-
XCTAssertEqual(plannedJobs.count, 3)
2738+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
27552739

2756-
let linkJob = plannedJobs[2]
2757-
let linkCmd = linkJob.commandLine
2758-
XCTAssertFalse(linkCmd.contains(.flag("-fsanitize=address")))
2740+
XCTAssertEqual(jobs.count, 3)
2741+
XCTAssertFalse(jobs[2].commandLine.contains(.flag("-fsanitize=address")))
27592742
}
27602743

2744+
#if !os(Windows)
27612745
do {
27622746
// thread sanitizer
27632747
var driver = try Driver(args: commonArgs + ["-sanitize=thread"])
@@ -2773,21 +2757,16 @@ final class SwiftDriverTests: XCTestCase {
27732757
let linkCmd = linkJob.commandLine
27742758
XCTAssertTrue(linkCmd.contains(.flag("-fsanitize=thread")))
27752759
}
2760+
#endif
27762761

27772762
do {
27782763
// undefined behavior sanitizer
27792764
var driver = try Driver(args: commonArgs + ["-sanitize=undefined"])
2780-
let plannedJobs = try driver.planBuild()
2781-
2782-
XCTAssertEqual(plannedJobs.count, 3)
2783-
2784-
let compileJob = plannedJobs[0]
2785-
let compileCmd = compileJob.commandLine
2786-
XCTAssertTrue(compileCmd.contains(.flag("-sanitize=undefined")))
2765+
let jobs = try driver.planBuild().removingAutolinkExtractJobs()
27872766

2788-
let linkJob = plannedJobs[2]
2789-
let linkCmd = linkJob.commandLine
2790-
XCTAssertTrue(linkCmd.contains(.flag("-fsanitize=undefined")))
2767+
XCTAssertEqual(jobs.count, 3)
2768+
XCTAssertJobInvocationMatches(jobs[0], .flag("-sanitize=undefined"))
2769+
XCTAssertJobInvocationMatches(jobs[2], .flag("-fsanitize=undefined"))
27912770
}
27922771

27932772
// FIXME: This test will fail when run on macOS, because the driver uses
@@ -7221,7 +7200,7 @@ final class SwiftDriverTests: XCTestCase {
72217200
}
72227201

72237202
func testSanitizerArgsForTargets() throws {
7224-
let targets = ["x86_64-unknown-freebsd", "x86_64-unknown-linux", "x86_64-apple-macosx10.9"]
7203+
let targets = ["x86_64-unknown-freebsd", "x86_64-unknown-linux", "x86_64-apple-macosx10.9", "x86_64-unknown-windows-msvc"]
72257204
try targets.forEach {
72267205
var driver = try Driver(args: ["swiftc", "-emit-module", "-target", $0, "foo.swift"])
72277206
_ = try driver.planBuild()

0 commit comments

Comments
 (0)