Skip to content

Commit d1077fb

Browse files
committed
WIP - UBSan support
1 parent 9486ee6 commit d1077fb

File tree

6 files changed

+76
-6
lines changed

6 files changed

+76
-6
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// swift-tools-version:4.2
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "CUBSan",
6+
targets: [
7+
.target(name: "CUBSan", path: "Sources"),
8+
.testTarget(name: "CUBSanTests", dependencies: ["CUBSan"]),
9+
]
10+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#import <Foundation/Foundation.h>
2+
#import "HelloWorldExample.h"
3+
4+
@implementation HelloWorld
5+
- (NSString *)hello:(NSString *)name {
6+
__builtin_unreachable();
7+
return @"";
8+
}
9+
@end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface HelloWorld : NSObject
4+
5+
- (NSString *)hello:(NSString *)name;
6+
7+
@end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#import <XCTest/XCTest.h>
2+
3+
# import "HelloWorldExample.h"
4+
5+
@interface HelloWorldTest : XCTestCase
6+
7+
@end
8+
9+
@implementation HelloWorldTest
10+
11+
- (HelloWorld *)helloWorld {
12+
return [[HelloWorld alloc] init];
13+
}
14+
15+
- (void)testNoName {
16+
NSString *input = nil;
17+
NSString *expected = @"Hello, World!";
18+
NSString *result = [[self helloWorld] hello:input];
19+
XCTAssertEqualObjects(expected, result);
20+
}
21+
22+
- (void)testSampleName {
23+
NSString *input = @"Alice";
24+
NSString *expected = @"Hello, Alice!";
25+
NSString *result = [[self helloWorld] hello:input];
26+
XCTAssertEqualObjects(expected, result);
27+
}
28+
29+
- (void)testOtherSampleName {
30+
NSString *input = @"Bob";
31+
NSString *expected = @"Hello, Bob!";
32+
NSString *result = [[self helloWorld] hello:input];
33+
XCTAssertEqualObjects(expected, result);
34+
}
35+
36+
@end

Sources/Build/BuildPlan.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ public final class ProductBuildDescription {
462462
public func linkArguments() -> [String] {
463463
var args = [buildParameters.toolchain.swiftCompiler.asString]
464464
args += buildParameters.toolchain.extraSwiftCFlags
465-
args += buildParameters.sanitizers.linkSwiftFlags()
465+
args += buildParameters.sanitizers.linkFlags()
466466
args += additionalFlags
467467

468468
if buildParameters.configuration == .debug {

Sources/Build/Sanitizers.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,20 @@ import Utility
1515
public enum Sanitizer: String {
1616
case address
1717
case thread
18+
case undefined
1819

1920
/// Return an established short name for a sanitizer, e.g. "asan".
2021
public var shortName: String {
2122
switch self {
2223
case .address: return "asan"
2324
case .thread: return "tsan"
25+
case .undefined: return "undefined"
2426
}
2527
}
28+
29+
public var flagName: String {
30+
return "-fsanitize=\(self.rawValue)"
31+
}
2632
}
2733

2834
/// A set of enabled runtime sanitizers.
@@ -39,17 +45,18 @@ public struct EnabledSanitizers {
3945

4046
/// Sanitization flags for the C family compiler (C/C++).
4147
public func compileCFlags() -> [String] {
42-
return sanitizers.map({ "-fsanitize=\($0.rawValue)" })
48+
return sanitizers.map{ $0.flagName }
4349
}
4450

4551
/// Sanitization flags for the Swift compiler.
4652
public func compileSwiftFlags() -> [String] {
47-
return sanitizers.map({ "-sanitize=\($0.rawValue)" })
53+
// UBSan is only available for C family languages
54+
return sanitizers.filter{ $0 != .undefined }.map{ $0.flagName }
4855
}
4956

50-
/// Sanitization flags for the Swift linker and compiler are the same so far.
51-
public func linkSwiftFlags() -> [String] {
52-
return compileSwiftFlags()
57+
/// Sanitization flags for the linker
58+
public func linkFlags() -> [String] {
59+
return sanitizers.map{ $0.flagName }
5360
}
5461

5562
public var isEmpty: Bool {
@@ -61,5 +68,6 @@ extension Sanitizer: StringEnumArgument {
6168
public static let completion: ShellCompletion = .values([
6269
(address.rawValue, "enable Address sanitizer"),
6370
(thread.rawValue, "enable Thread sanitizer"),
71+
(undefined.rawValue, "enable Undefined Behavior sanitizer"),
6472
])
6573
}

0 commit comments

Comments
 (0)