Skip to content

Commit 6d46af5

Browse files
committed
Validate profile generation args
1 parent 5d80fe4 commit 6d46af5

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public struct Driver {
2727
case unableToLoadOutputFileMap(String)
2828
case unableToDecodeFrontendTargetInfo
2929
case failedToRetrieveFrontendTargetInfo
30+
case missingProfilingData(String)
3031
// Explicit Module Build Failures
3132
case malformedModuleDependency(String, String)
3233
case missingPCMArguments(String)
@@ -55,6 +56,8 @@ public struct Driver {
5556
return "could not decode frontend target info; compiler driver and frontend executables may be incompatible"
5657
case .failedToRetrieveFrontendTargetInfo:
5758
return "failed to retrieve frontend target info"
59+
case .missingProfilingData(let arg):
60+
return "no profdata file exists at '\(arg)'"
5861
// Explicit Module Build Failures
5962
case .malformedModuleDependency(let moduleName, let errorDescription):
6063
return "Malformed Module Dependency: \(moduleName), \(errorDescription)"
@@ -328,6 +331,9 @@ public struct Driver {
328331
self.numParallelJobs = Self.determineNumParallelJobs(&parsedOptions, diagnosticsEngine: diagnosticEngine, env: env)
329332

330333
try Self.validateWarningControlArgs(&parsedOptions)
334+
try Self.validateProfilingArgs(&parsedOptions,
335+
fileSystem: fileSystem,
336+
workingDirectory: workingDirectory)
331337
Self.validateCoverageArgs(&parsedOptions, diagnosticsEngine: diagnosticEngine)
332338
try toolchain.validateArgs(&parsedOptions,
333339
targetTriple: self.frontendTargetInfo.target.triple,
@@ -1565,6 +1571,25 @@ extension Driver {
15651571
}
15661572
}
15671573

1574+
static func validateProfilingArgs(_ parsedOptions: inout ParsedOptions,
1575+
fileSystem: FileSystem,
1576+
workingDirectory: AbsolutePath?) throws {
1577+
if parsedOptions.hasArgument(.profileGenerate) &&
1578+
parsedOptions.hasArgument(.profileUse) {
1579+
throw Error.conflictingOptions(.profileGenerate, .profileUse)
1580+
}
1581+
1582+
if let profileArgs = parsedOptions.getLastArgument(.profileUse)?.asMultiple,
1583+
let workingDirectory = workingDirectory ?? fileSystem.currentWorkingDirectory {
1584+
for profilingData in profileArgs {
1585+
guard fileSystem.exists(AbsolutePath(profilingData,
1586+
relativeTo: workingDirectory)) else {
1587+
throw Error.missingProfilingData(profilingData)
1588+
}
1589+
}
1590+
}
1591+
}
1592+
15681593
private static func validateCoverageArgs(_ parsedOptions: inout ParsedOptions, diagnosticsEngine: DiagnosticsEngine) {
15691594
for coveragePrefixMap in parsedOptions.arguments(for: .coveragePrefixMap) {
15701595
let value = coveragePrefixMap.argument.asSingle

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,32 @@ final class SwiftDriverTests: XCTestCase {
16641664
try assertNoDriverDiagnostics(args: "swiftc", "-c", "-target", "x86_64-apple-macosx10.14", "-link-objc-runtime", "foo.swift")
16651665
}
16661666

1667+
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))
1670+
}
1671+
1672+
XCTAssertThrowsError(try Driver(args: ["swiftc", "foo.swift", "-profile-use=profile.profdata"])) {
1673+
XCTAssertEqual($0 as? Driver.Error, .missingProfilingData("profile.profdata"))
1674+
}
1675+
1676+
try withTemporaryDirectory { path in
1677+
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+
}
1680+
1681+
try withTemporaryDirectory { path in
1682+
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+
}
1689+
}
1690+
}
1691+
}
1692+
16671693
// Test cases ported from Driver/macabi-environment.swift
16681694
func testDarwinSDKVersioning() throws {
16691695
try withTemporaryDirectory { tmpDir in

0 commit comments

Comments
 (0)