Skip to content

Commit 3b60ea5

Browse files
committed
Sanitizers: Address and thread sanitizers config changes
Update the Address and Thread sanitizers XCspect properties to support using clang and swiftc as a linker.
1 parent c66f413 commit 3b60ea5

File tree

6 files changed

+155
-7
lines changed

6 files changed

+155
-7
lines changed

Sources/SWBTestSupport/SwiftTestingExtensions.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,14 @@ package import Testing
1717
package func expectEqual<T: Equatable>(_ lhs: T, _ rhs: T, sourceLocation: SourceLocation = #_sourceLocation) {
1818
#expect(lhs == rhs, sourceLocation: sourceLocation)
1919
}
20+
21+
22+
package extension Tag {
23+
enum TestSize {}
24+
}
25+
26+
package extension Tag.TestSize {
27+
@Tag static var small: Tag
28+
@Tag static var medium: Tag
29+
@Tag static var large: Tag
30+
}

Sources/SWBUniversalPlatform/Specs/Clang.xcspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2896,7 +2896,7 @@
28962896
};
28972897
AdditionalLinkerArgs = {
28982898
YES = (
2899-
"-fsanitize=address",
2899+
"$(LD_ADDRESS_SANITIZER)",
29002900
);
29012901
NO = ();
29022902
};

Sources/SWBUniversalPlatform/Specs/Ld.xcspec

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,17 +582,37 @@
582582
DefaultValue = YES;
583583
},
584584

585+
// Address Sanitizer options
586+
{
587+
Name = LD_ADDRESS_SANITIZER;
588+
DefaultValue = "$(LD_ADDRESS_SANITIZER_$(LINKER_DRIVER))";
589+
},
590+
{
591+
Name = LD_ADDRESS_SANITIZER_clang;
592+
DefaultValue = "-fsanitize=address";
593+
},
594+
{
595+
Name = LD_ADDRESS_SANITIZER_swiftc;
596+
DefaultValue = "-sanitize=address";
597+
},
598+
585599
// Thread Sanitizer options
586600
{
587601
Name = "LD_THREAD_SANITIZER";
588602
Type = Boolean;
589603
DefaultValue = "$(ENABLE_THREAD_SANITIZER)";
604+
},
605+
{
606+
Name = "CLANG_LD_THREAD_SANITIZER";
607+
Type = Boolean;
608+
DefaultValue = "$(LD_THREAD_SANITIZER)";
590609
Architectures = (
591610
x86_64,
592611
x86_64h,
593612
arm64,
594613
arm64e,
595614
);
615+
Condition = "$(LINKER_DRIVER) == clang";
596616
CommandLineArgs = {
597617
YES = (
598618
"-fsanitize=thread",
@@ -601,6 +621,25 @@
601621
};
602622
// Not visible in the build settings editor
603623
},
624+
{
625+
Name = "SWIFTC_LD_THREAD_SANITIZER";
626+
Type = Boolean;
627+
DefaultValue = "$(LD_THREAD_SANITIZER)";
628+
Architectures = (
629+
x86_64,
630+
x86_64h,
631+
arm64,
632+
arm64e,
633+
);
634+
Condition = "$(LINKER_DRIVER) == swiftc";
635+
CommandLineArgs = {
636+
YES = (
637+
"-sanitize=thread",
638+
);
639+
NO = ();
640+
};
641+
// Not visible in the build settings editor
642+
},
604643

605644
{
606645
Name = "LD_DEBUG_VARIANT";

Sources/SWBUniversalPlatform/Specs/Swift.xcspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@
12251225
};
12261226
AdditionalLinkerArgs = {
12271227
YES = (
1228-
"-fsanitize=address",
1228+
"$(LD_ADDRESS_SANITIZER)",
12291229
);
12301230
NO = ();
12311231
};

Tests/SWBTaskConstructionTests/LinkerTaskConstructionTests.swift

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,89 @@ fileprivate struct LinkerTaskConstructionTests: CoreBasedTests {
141141
}
142142
}
143143
}
144+
145+
@Test(
146+
.tags(
147+
.TestSize.medium,
148+
),
149+
.requireSDKs(.host),
150+
arguments: [
151+
(
152+
buildSettingNameUT: "ENABLE_ADDRESS_SANITIZER",
153+
linkerDriverUT: "clang",
154+
expectedArgument: "-fsanitize=address",
155+
),
156+
(
157+
buildSettingNameUT: "ENABLE_ADDRESS_SANITIZER",
158+
linkerDriverUT: "swiftc",
159+
expectedArgument: "-sanitize=address",
160+
),
161+
(
162+
buildSettingNameUT: "ENABLE_THREAD_SANITIZER",
163+
linkerDriverUT: "clang",
164+
expectedArgument: "-fsanitize=thread",
165+
),
166+
(
167+
buildSettingNameUT: "ENABLE_THREAD_SANITIZER",
168+
linkerDriverUT: "swiftc",
169+
expectedArgument: "-sanitize=thread",
170+
),
171+
]
172+
)
173+
func ldSanitizerArgumentsAppearsOnCommandLine(
174+
buildSettingNameUT: String,
175+
linkerDriverUT: String,
176+
expectedArgument: String,
177+
) async throws {
178+
let testProject = TestProject(
179+
"aProject",
180+
groupTree: TestGroup(
181+
"SomeFiles",
182+
children: [
183+
TestFile("c.c"),
184+
TestFile("cxx.cpp"),
185+
TestFile("s.swift"),
186+
]),
187+
buildConfigurations: [
188+
TestBuildConfiguration("Debug", buildSettings: [
189+
"PRODUCT_NAME": "$(TARGET_NAME)",
190+
"SWIFT_EXEC": try await swiftCompilerPath.str,
191+
"SWIFT_VERSION": try await swiftVersion
192+
]),
193+
],
194+
targets: [
195+
TestStandardTarget(
196+
"Library",
197+
type: .dynamicLibrary,
198+
buildConfigurations: [
199+
TestBuildConfiguration("Debug", buildSettings: [:]),
200+
],
201+
buildPhases: [
202+
TestSourcesBuildPhase(["c.c", "cxx.cpp", "s.swift"]),
203+
]
204+
),
205+
],
206+
)
207+
let core = try await getCore()
208+
let tester = try TaskConstructionTester(core, testProject)
209+
let buildOverrides = [
210+
"LINKER_DRIVER": linkerDriverUT,
211+
buildSettingNameUT: "YES",
212+
]
213+
214+
await tester.checkBuild(
215+
BuildParameters(
216+
configuration: "Debug",
217+
overrides: buildOverrides,
218+
),
219+
runDestination: .host,
220+
) { results in
221+
results.checkNoDiagnostics()
222+
results.checkTask(.matchRuleType("Ld")) { task in
223+
task.checkCommandLineContains([expectedArgument])
224+
}
225+
}
226+
227+
}
228+
144229
}

Tests/SWBTaskConstructionTests/TaskConstructionTests.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4061,8 +4061,17 @@ fileprivate struct TaskConstructionTests: CoreBasedTests {
40614061
}
40624062

40634063
/// Test that we properly generate commands for the compiler sanitizer features.
4064-
@Test(.requireSDKs(.macOS))
4065-
func sanitizers() async throws {
4064+
@Test(
4065+
.requireSDKs(.macOS),
4066+
arguments:[
4067+
(linkerDriver: "clang", expectedArgument: "-fsanitize=address"),
4068+
(linkerDriver: "swiftc", expectedArgument: "-sanitize=address"),
4069+
],
4070+
)
4071+
func sanitizers(
4072+
linkerDriver: String,
4073+
expectedArgument: String,
4074+
) async throws {
40664075
try await withTemporaryDirectory { tmpDir in
40674076
let targetName = "AppTarget"
40684077
let testProject = try await TestProject(
@@ -4115,7 +4124,7 @@ fileprivate struct TaskConstructionTests: CoreBasedTests {
41154124
}
41164125

41174126
// Check the LibSystem address sanitizer.
4118-
await tester.checkBuild(BuildParameters(configuration: "Debug", overrides: ["ENABLE_ADDRESS_SANITIZER": "YES","ENABLE_SYSTEM_SANITIZERS": "YES" ]), runDestination: .macOS, fs: fs) { results in
4127+
await tester.checkBuild(BuildParameters(configuration: "Debug", overrides: ["LINKER_DRIVER": linkerDriver,"ENABLE_ADDRESS_SANITIZER": "YES","ENABLE_SYSTEM_SANITIZERS": "YES" ]), runDestination: .macOS, fs: fs) { results in
41194128
results.checkTarget(targetName) { target in
41204129
// There should be one CompileC task, which includes the ASan option, and which puts its output in a -asan directory.
41214130
results.checkTask(.matchTarget(target), .matchRuleType("CompileC")) { task in
@@ -4129,8 +4138,12 @@ fileprivate struct TaskConstructionTests: CoreBasedTests {
41294138
}
41304139
results.checkTask(.matchTarget(target), .matchRuleType("Ld")) { task in
41314140
task.checkCommandLineContains(
4132-
["-fsanitize=address", "-fsanitize-stable-abi", "\(SRCROOT)/build/Debug/\(targetName).app/Contents/MacOS/\(targetName)"
4133-
])
4141+
[
4142+
expectedArgument,
4143+
"-fsanitize-stable-abi",
4144+
"\(SRCROOT)/build/Debug/\(targetName).app/Contents/MacOS/\(targetName)",
4145+
]
4146+
)
41344147
}
41354148
}
41364149
}

0 commit comments

Comments
 (0)