Skip to content

Commit c9f696d

Browse files
committed
Don't skip argument validation steps if an earlier step failed
1 parent 5982e80 commit c9f696d

File tree

4 files changed

+65
-51
lines changed

4 files changed

+65
-51
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,13 @@ public struct Driver {
342342
self.numThreads = Self.determineNumThreads(&parsedOptions, compilerMode: compilerMode, diagnosticsEngine: diagnosticEngine)
343343
self.numParallelJobs = Self.determineNumParallelJobs(&parsedOptions, diagnosticsEngine: diagnosticEngine, env: env)
344344

345-
try Self.validateWarningControlArgs(&parsedOptions)
346-
try Self.validateProfilingArgs(&parsedOptions,
347-
fileSystem: fileSystem,
348-
workingDirectory: workingDirectory)
349-
try Self.validateCompilationConditionArgs(&parsedOptions)
350-
try Self.validateFrameworkSearchPathArgs(&parsedOptions)
345+
Self.validateWarningControlArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
346+
Self.validateProfilingArgs(&parsedOptions,
347+
fileSystem: fileSystem,
348+
workingDirectory: workingDirectory,
349+
diagnosticEngine: diagnosticEngine)
350+
Self.validateCompilationConditionArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
351+
Self.validateFrameworkSearchPathArgs(&parsedOptions, diagnosticEngine: diagnosticEngine)
351352
Self.validateCoverageArgs(&parsedOptions, diagnosticsEngine: diagnosticEngine)
352353
try toolchain.validateArgs(&parsedOptions,
353354
targetTriple: self.frontendTargetInfo.target.triple,
@@ -1578,50 +1579,52 @@ extension Diagnostic.Message {
15781579

15791580
// MARK: Miscellaneous Argument Validation
15801581
extension Driver {
1581-
static func validateWarningControlArgs(_ parsedOptions: inout ParsedOptions) throws {
1582+
static func validateWarningControlArgs(_ parsedOptions: inout ParsedOptions,
1583+
diagnosticEngine: DiagnosticsEngine) {
15821584
if parsedOptions.hasArgument(.suppressWarnings) &&
15831585
parsedOptions.hasFlag(positive: .warningsAsErrors, negative: .noWarningsAsErrors, default: false) {
1584-
throw Error.conflictingOptions(.warningsAsErrors, .suppressWarnings)
1586+
diagnosticEngine.emit(Error.conflictingOptions(.warningsAsErrors, .suppressWarnings))
15851587
}
15861588
}
15871589

15881590
static func validateProfilingArgs(_ parsedOptions: inout ParsedOptions,
15891591
fileSystem: FileSystem,
1590-
workingDirectory: AbsolutePath?) throws {
1592+
workingDirectory: AbsolutePath?,
1593+
diagnosticEngine: DiagnosticsEngine) {
15911594
if parsedOptions.hasArgument(.profileGenerate) &&
15921595
parsedOptions.hasArgument(.profileUse) {
1593-
throw Error.conflictingOptions(.profileGenerate, .profileUse)
1596+
diagnosticEngine.emit(Error.conflictingOptions(.profileGenerate, .profileUse))
15941597
}
15951598

15961599
if let profileArgs = parsedOptions.getLastArgument(.profileUse)?.asMultiple,
15971600
let workingDirectory = workingDirectory ?? fileSystem.currentWorkingDirectory {
15981601
for profilingData in profileArgs {
1599-
guard fileSystem.exists(AbsolutePath(profilingData,
1600-
relativeTo: workingDirectory)) else {
1601-
throw Error.missingProfilingData(profilingData)
1602+
if !fileSystem.exists(AbsolutePath(profilingData,
1603+
relativeTo: workingDirectory)) {
1604+
diagnosticEngine.emit(Error.missingProfilingData(profilingData))
16021605
}
16031606
}
16041607
}
16051608
}
16061609

1607-
static func validateCompilationConditionArgs(_ parsedOptions: inout ParsedOptions) throws {
1610+
static func validateCompilationConditionArgs(_ parsedOptions: inout ParsedOptions,
1611+
diagnosticEngine: DiagnosticsEngine) {
16081612
for arg in parsedOptions.arguments(for: .D).map(\.argument.asSingle) {
1609-
guard !arg.contains("=") else {
1610-
throw Error.cannotAssignToConditionalCompilationFlag(arg)
1611-
}
1612-
guard !arg.hasPrefix("-D") else {
1613-
throw Error.conditionalCompilationFlagHasRedundantPrefix(arg)
1614-
}
1615-
guard arg.sd_isSwiftIdentifier else {
1616-
throw Error.conditionalCompilationFlagIsNotValidIdentifier(arg)
1613+
if arg.contains("=") {
1614+
diagnosticEngine.emit(Error.cannotAssignToConditionalCompilationFlag(arg))
1615+
} else if arg.hasPrefix("-D") {
1616+
diagnosticEngine.emit(Error.conditionalCompilationFlagHasRedundantPrefix(arg))
1617+
} else if !arg.sd_isSwiftIdentifier {
1618+
diagnosticEngine.emit(Error.conditionalCompilationFlagIsNotValidIdentifier(arg))
16171619
}
16181620
}
16191621
}
16201622

1621-
static func validateFrameworkSearchPathArgs(_ parsedOptions: inout ParsedOptions) throws {
1623+
static func validateFrameworkSearchPathArgs(_ parsedOptions: inout ParsedOptions,
1624+
diagnosticEngine: DiagnosticsEngine) {
16221625
for arg in parsedOptions.arguments(for: .F, .Fsystem).map(\.argument.asSingle) {
16231626
if arg.hasSuffix(".framework") || arg.hasSuffix(".framework/") {
1624-
throw Error.frameworkSearchPathIncludesExtension(arg)
1627+
diagnosticEngine.emit(Error.frameworkSearchPathIncludesExtension(arg))
16251628
}
16261629
}
16271630
}

Sources/swift-driver/main.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ do {
4747
var driver = try Driver(args: arguments,
4848
diagnosticsEngine: diagnosticsEngine,
4949
executor: executor)
50+
// FIXME: The following check should be at the end of Driver.init, but current
51+
// usage of the DiagnosticVerifier in tests makes this difficult.
52+
guard !driver.diagnosticEngine.hasErrors else { throw Diagnostics.fatalError }
53+
5054
let jobs = try driver.planBuild()
5155
try driver.run(jobs: jobs)
5256

Tests/SwiftDriverTests/Helpers/AssertDiagnostics.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import XCTest
1414
import SwiftDriver
1515
import TSCBasic
16+
import TSCUtility
1617

1718
func assertDriverDiagnostics(
1819
args: [String],

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,61 +1665,67 @@ final class SwiftDriverTests: XCTestCase {
16651665
}
16661666

16671667
func testProfileArgValidation() throws {
1668-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-profile-generate", "-profile-use=profile.profdata"])) {
1669-
XCTAssertEqual($0 as? Driver.Error, .conflictingOptions(.profileGenerate, .profileUse))
1668+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-profile-generate", "-profile-use=profile.profdata"]) {
1669+
$1.expect(.error(Driver.Error.conflictingOptions(.profileGenerate, .profileUse)))
1670+
$1.expect(.error(Driver.Error.missingProfilingData("profile.profdata")))
16701671
}
16711672

1672-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-profile-use=profile.profdata"])) {
1673-
XCTAssertEqual($0 as? Driver.Error, .missingProfilingData("profile.profdata"))
1673+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-profile-use=profile.profdata"]) {
1674+
$1.expect(.error(Driver.Error.missingProfilingData("profile.profdata")))
16741675
}
16751676

16761677
try withTemporaryDirectory { path in
16771678
try localFileSystem.writeFileContents(path.appending(component: "profile.profdata"), bytes: .init())
1678-
XCTAssertNoThrow(try Driver(args: ["swiftc", "-working-directory", path.pathString, "foo.swift", "-profile-use=profile.profdata"]))
1679+
try assertNoDriverDiagnostics(args: "swiftc", "-working-directory", path.pathString, "foo.swift", "-profile-use=profile.profdata")
16791680
}
16801681

16811682
try withTemporaryDirectory { path in
16821683
try localFileSystem.writeFileContents(path.appending(component: "profile.profdata"), bytes: .init())
1683-
XCTAssertThrowsError(try Driver(args: ["swiftc", "-working-directory", path.pathString, "foo.swift",
1684-
"-profile-use=profile.profdata,profile2.profdata"])) {
1685-
guard case Driver.Error.missingProfilingData = $0 else {
1686-
XCTFail()
1687-
return
1688-
}
1684+
try assertDriverDiagnostics(args: ["swiftc", "-working-directory", path.pathString, "foo.swift",
1685+
"-profile-use=profile.profdata,profile2.profdata"]) {
1686+
$1.expect(.error(Driver.Error.missingProfilingData(path.appending(component: "profile2.profdata").pathString)))
16891687
}
16901688
}
16911689
}
16921690

16931691
func testConditionalCompilationArgValidation() throws {
1694-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-DFOO=BAR"])) {
1695-
XCTAssertEqual($0 as? Driver.Error, .cannotAssignToConditionalCompilationFlag("FOO=BAR"))
1692+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-DFOO=BAR"]) {
1693+
$1.expect(.error(Driver.Error.cannotAssignToConditionalCompilationFlag("FOO=BAR")))
16961694
}
16971695

1698-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-D-DFOO"])) {
1699-
XCTAssertEqual($0 as? Driver.Error, .conditionalCompilationFlagHasRedundantPrefix("-DFOO"))
1696+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-D-DFOO"]) {
1697+
$1.expect(.error(Driver.Error.conditionalCompilationFlagHasRedundantPrefix("-DFOO")))
17001698
}
17011699

1702-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-Dnot-an-identifier"])) {
1703-
XCTAssertEqual($0 as? Driver.Error, .conditionalCompilationFlagIsNotValidIdentifier("not-an-identifier"))
1700+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-Dnot-an-identifier"]) {
1701+
$1.expect(.error(Driver.Error.conditionalCompilationFlagIsNotValidIdentifier("not-an-identifier")))
17041702
}
17051703

1706-
XCTAssertNoThrow(try Driver(args: ["swiftc", "foo.swift", "-DFOO"]))
1704+
try assertNoDriverDiagnostics(args: "swiftc", "foo.swift", "-DFOO")
17071705
}
17081706

17091707
func testFrameworkSearchPathArgValidation() throws {
1710-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-F/some/dir/xyz.framework"])) {
1711-
XCTAssertEqual($0 as? Driver.Error, .frameworkSearchPathIncludesExtension("/some/dir/xyz.framework"))
1708+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-F/some/dir/xyz.framework"]) {
1709+
$1.expect(.error(Driver.Error.frameworkSearchPathIncludesExtension("/some/dir/xyz.framework")))
17121710
}
17131711

1714-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-F/some/dir/xyz.framework/"])) {
1715-
XCTAssertEqual($0 as? Driver.Error, .frameworkSearchPathIncludesExtension("/some/dir/xyz.framework/"))
1712+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-F/some/dir/xyz.framework/"]) {
1713+
$1.expect(.error(Driver.Error.frameworkSearchPathIncludesExtension("/some/dir/xyz.framework/")))
17161714
}
17171715

1718-
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-Fsystem", "/some/dir/xyz.framework"])) {
1719-
XCTAssertEqual($0 as? Driver.Error, .frameworkSearchPathIncludesExtension("/some/dir/xyz.framework"))
1716+
try assertDriverDiagnostics(args: ["swiftc", "foo.swift", "-Fsystem", "/some/dir/xyz.framework"]) {
1717+
$1.expect(.error(Driver.Error.frameworkSearchPathIncludesExtension("/some/dir/xyz.framework")))
17201718
}
17211719

1722-
XCTAssertNoThrow(try Driver(args: ["swiftc", "foo.swift", "-Fsystem", "/some/dir/"]))
1720+
try assertNoDriverDiagnostics(args: "swiftc", "foo.swift", "-Fsystem", "/some/dir/")
1721+
}
1722+
1723+
func testMultipleValidationFailures() throws {
1724+
try assertDiagnostics { engine, verifier in
1725+
verifier.expect(.error(Driver.Error.conditionalCompilationFlagIsNotValidIdentifier("not-an-identifier")))
1726+
verifier.expect(.error(Driver.Error.frameworkSearchPathIncludesExtension("/some/dir/xyz.framework")))
1727+
_ = try Driver(args: ["swiftc", "foo.swift", "-Dnot-an-identifier", "-F/some/dir/xyz.framework"], diagnosticsEngine: engine)
1728+
}
17231729
}
17241730

17251731
// Test cases ported from Driver/macabi-environment.swift
@@ -2368,8 +2374,8 @@ final class SwiftDriverTests: XCTestCase {
23682374
}
23692375

23702376
do {
2371-
XCTAssertThrowsError(try Driver(args: ["swift", "-no-warnings-as-errors", "-warnings-as-errors", "-suppress-warnings", "foo.swift"])) {
2372-
XCTAssertEqual($0 as? Driver.Error, Driver.Error.conflictingOptions(.warningsAsErrors, .suppressWarnings))
2377+
try assertDriverDiagnostics(args: ["swift", "-no-warnings-as-errors", "-warnings-as-errors", "-suppress-warnings", "foo.swift"]) {
2378+
$1.expect(.error(Driver.Error.conflictingOptions(.warningsAsErrors, .suppressWarnings)))
23732379
}
23742380
}
23752381

0 commit comments

Comments
 (0)