Skip to content

Commit 848b3eb

Browse files
authored
[Driver] Make sure to rebuild dependents when a dirty file fails. (swiftlang#3935)
Otherwise we get into a situation like this: 1. Change made to the interface of file A.swift that also causes an error in A.swift. 2. Fixing the error in A.swift does not affect A.swift's interface. 3. File B.swift that depends on A.swift is not rebuilt, since the most recent change to A.swift did not change its interface. To fix this, mark downstream files as needing to be rebuilt even when a compilation job fails with errors. Additionally, attempt to be extra conservative when there's a crash. rdar://problem/25405605
1 parent 7383696 commit 848b3eb

30 files changed

+533
-79
lines changed

lib/Driver/Compilation.cpp

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,70 @@ int Compilation::performJobsImpl() {
456456
llvm::errs() << Output;
457457
}
458458

459+
// In order to handle both old dependencies that have disappeared and new
460+
// dependencies that have arisen, we need to reload the dependency file.
461+
// Do this whether or not the build succeeded.
462+
SmallVector<const Job *, 16> Dependents;
463+
if (getIncrementalBuildEnabled()) {
464+
const CommandOutput &Output = FinishedCmd->getOutput();
465+
StringRef DependenciesFile =
466+
Output.getAdditionalOutputForType(types::TY_SwiftDeps);
467+
if (!DependenciesFile.empty() &&
468+
(ReturnCode == EXIT_SUCCESS || ReturnCode == EXIT_FAILURE)) {
469+
bool wasCascading = DepGraph.isMarked(FinishedCmd);
470+
471+
switch (DepGraph.loadFromPath(FinishedCmd, DependenciesFile)) {
472+
case DependencyGraphImpl::LoadResult::HadError:
473+
if (ReturnCode == EXIT_SUCCESS) {
474+
disableIncrementalBuild();
475+
for (const Job *Cmd : DeferredCommands)
476+
scheduleCommandIfNecessaryAndPossible(Cmd);
477+
DeferredCommands.clear();
478+
Dependents.clear();
479+
} // else, let the next build handle it.
480+
break;
481+
case DependencyGraphImpl::LoadResult::UpToDate:
482+
if (!wasCascading)
483+
break;
484+
SWIFT_FALLTHROUGH;
485+
case DependencyGraphImpl::LoadResult::AffectsDownstream:
486+
llvm::errs() << "DOWNSTREAM " << ReturnCode << "\n";
487+
DepGraph.markTransitive(Dependents, FinishedCmd);
488+
break;
489+
}
490+
} else {
491+
// If there's a crash, assume the worst.
492+
switch (FinishedCmd->getCondition()) {
493+
case Job::Condition::NewlyAdded:
494+
// The job won't be treated as newly added next time. Conservatively
495+
// mark it as affecting other jobs, because some of them may have
496+
// completed already.
497+
DepGraph.markTransitive(Dependents, FinishedCmd);
498+
break;
499+
case Job::Condition::Always:
500+
// This applies to non-incremental tasks as well, but any incremental
501+
// task that shows up here has already been marked.
502+
break;
503+
case Job::Condition::RunWithoutCascading:
504+
// If this file changed, it might have been a non-cascading change and
505+
// it might not. Unfortunately, the interface hash has been updated or
506+
// compromised, so we don't actually know anymore; we have to
507+
// conservatively assume the changes could affect other files.
508+
DepGraph.markTransitive(Dependents, FinishedCmd);
509+
break;
510+
case Job::Condition::CheckDependencies:
511+
// If the only reason we're running this is because something else
512+
// changed, then we can trust the dependency graph as to whether it's
513+
// a cascading or non-cascading change. That is, if whatever /caused/
514+
// the error isn't supposed to affect other files, and whatever
515+
// /fixes/ the error isn't supposed to affect other files, then
516+
// there's no need to recompile any other inputs. If either of those
517+
// are false, we /do/ need to recompile other inputs.
518+
break;
519+
}
520+
}
521+
}
522+
459523
if (ReturnCode != EXIT_SUCCESS) {
460524
// The task failed, so return true without performing any further
461525
// dependency analysis.
@@ -481,39 +545,10 @@ int Compilation::performJobsImpl() {
481545
// might have been blocked.
482546
markFinished(FinishedCmd);
483547

484-
// In order to handle both old dependencies that have disappeared and new
485-
// dependencies that have arisen, we need to reload the dependency file.
486-
if (getIncrementalBuildEnabled()) {
487-
const CommandOutput &Output = FinishedCmd->getOutput();
488-
StringRef DependenciesFile =
489-
Output.getAdditionalOutputForType(types::TY_SwiftDeps);
490-
if (!DependenciesFile.empty()) {
491-
SmallVector<const Job *, 16> Dependents;
492-
bool wasCascading = DepGraph.isMarked(FinishedCmd);
493-
494-
switch (DepGraph.loadFromPath(FinishedCmd, DependenciesFile)) {
495-
case DependencyGraphImpl::LoadResult::HadError:
496-
disableIncrementalBuild();
497-
for (const Job *Cmd : DeferredCommands)
498-
scheduleCommandIfNecessaryAndPossible(Cmd);
499-
DeferredCommands.clear();
500-
Dependents.clear();
501-
break;
502-
case DependencyGraphImpl::LoadResult::UpToDate:
503-
if (!wasCascading)
504-
break;
505-
SWIFT_FALLTHROUGH;
506-
case DependencyGraphImpl::LoadResult::AffectsDownstream:
507-
DepGraph.markTransitive(Dependents, FinishedCmd);
508-
break;
509-
}
510-
511-
for (const Job *Cmd : Dependents) {
512-
DeferredCommands.erase(Cmd);
513-
noteBuilding(Cmd, "because of dependencies discovered later");
514-
scheduleCommandIfNecessaryAndPossible(Cmd);
515-
}
516-
}
548+
for (const Job *Cmd : Dependents) {
549+
DeferredCommands.erase(Cmd);
550+
noteBuilding(Cmd, "because of dependencies discovered later");
551+
scheduleCommandIfNecessaryAndPossible(Cmd);
517552
}
518553

519554
return TaskFinishedResponse::ContinueExecution;

lib/Driver/Driver.cpp

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,36 +1604,40 @@ handleCompileJobCondition(Job *J, CompileJobAction::InputInfo inputInfo,
16041604
return;
16051605
}
16061606

1607-
if (!alwaysRebuildDependents) {
1608-
// Default all non-newly added files to being rebuilt without cascading.
1609-
J->setCondition(Job::Condition::RunWithoutCascading);
1610-
}
1611-
1607+
bool hasValidModTime = false;
16121608
llvm::sys::fs::file_status inputStatus;
1613-
if (llvm::sys::fs::status(input, inputStatus))
1614-
return;
1615-
1616-
J->setInputModTime(inputStatus.getLastModificationTime());
1617-
if (J->getInputModTime() != inputInfo.previousModTime)
1618-
return;
1609+
if (!llvm::sys::fs::status(input, inputStatus)) {
1610+
J->setInputModTime(inputStatus.getLastModificationTime());
1611+
hasValidModTime = true;
1612+
}
16191613

16201614
Job::Condition condition;
1621-
switch (inputInfo.status) {
1622-
case CompileJobAction::InputInfo::UpToDate:
1623-
if (!llvm::sys::fs::exists(J->getOutput().getPrimaryOutputFilename()))
1615+
if (!hasValidModTime || J->getInputModTime() != inputInfo.previousModTime) {
1616+
if (alwaysRebuildDependents ||
1617+
inputInfo.status == CompileJobAction::InputInfo::NeedsCascadingBuild) {
1618+
condition = Job::Condition::Always;
1619+
} else {
16241620
condition = Job::Condition::RunWithoutCascading;
1625-
else
1626-
condition = Job::Condition::CheckDependencies;
1627-
break;
1628-
case CompileJobAction::InputInfo::NeedsCascadingBuild:
1629-
condition = Job::Condition::Always;
1630-
break;
1631-
case CompileJobAction::InputInfo::NeedsNonCascadingBuild:
1632-
condition = Job::Condition::RunWithoutCascading;
1633-
break;
1634-
case CompileJobAction::InputInfo::NewlyAdded:
1635-
llvm_unreachable("handled above");
1621+
}
1622+
} else {
1623+
switch (inputInfo.status) {
1624+
case CompileJobAction::InputInfo::UpToDate:
1625+
if (!llvm::sys::fs::exists(J->getOutput().getPrimaryOutputFilename()))
1626+
condition = Job::Condition::RunWithoutCascading;
1627+
else
1628+
condition = Job::Condition::CheckDependencies;
1629+
break;
1630+
case CompileJobAction::InputInfo::NeedsCascadingBuild:
1631+
condition = Job::Condition::Always;
1632+
break;
1633+
case CompileJobAction::InputInfo::NeedsNonCascadingBuild:
1634+
condition = Job::Condition::RunWithoutCascading;
1635+
break;
1636+
case CompileJobAction::InputInfo::NewlyAdded:
1637+
llvm_unreachable("handled above");
1638+
}
16361639
}
1640+
16371641
J->setCondition(condition);
16381642
}
16391643

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Dependencies after compilation:
2+
provides-top-level: [a]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Dependencies after compilation:
2+
depends-top-level: [a]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Dependencies after compilation:
2+
depends-top-level: [!private a]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"./main.swift": {
3+
"object": "./main.o",
4+
"swift-dependencies": "./main.swiftdeps"
5+
},
6+
"./crash.swift": {
7+
"object": "./crash.o",
8+
"swift-dependencies": "./crash.swiftdeps"
9+
},
10+
"./other.swift": {
11+
"object": "./other.o",
12+
"swift-dependencies": "./other.swiftdeps"
13+
},
14+
"": {
15+
"swift-dependencies": "./main~buildrecord.swiftdeps"
16+
}
17+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Dependencies after compilation:
2+
provides-top-level: [bad]
3+
interface-hash: "after"
4+
garbage: ""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies before compilation:
2+
provides-top-level: [bad]
3+
interface-hash: "before"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies after compilation:
2+
depends-top-level: [bad]
3+
interface-hash: "after"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies before compilation:
2+
depends-top-level: [bad]
3+
interface-hash: "before"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies after compilation:
2+
depends-top-level: [main]
3+
interface-hash: "after"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies before compilation:
2+
depends-top-level: [main]
3+
interface-hash: "before"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies after compilation:
2+
provides-top-level: [main]
3+
interface-hash: "after"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Dependencies before compilation:
2+
provides-top-level: [main]
3+
interface-hash: "before"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"./main.swift": {
3+
"object": "./main.o",
4+
"swift-dependencies": "./main.swiftdeps"
5+
},
6+
"./bad.swift": {
7+
"object": "./bad.o",
8+
"swift-dependencies": "./bad.swiftdeps"
9+
},
10+
"./depends-on-main.swift": {
11+
"object": "./depends-on-main.o",
12+
"swift-dependencies": "./depends-on-main.swiftdeps"
13+
},
14+
"./depends-on-bad.swift": {
15+
"object": "./depends-on-bad.o",
16+
"swift-dependencies": "./depends-on-bad.swiftdeps"
17+
},
18+
"": {
19+
"swift-dependencies": "./main~buildrecord.swiftdeps"
20+
}
21+
}

test/Driver/Dependencies/Inputs/update-dependencies-bad.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,38 @@
1111
#
1212
# ----------------------------------------------------------------------------
1313
#
14-
# Fails if the input file is named "bad.swift"; otherwise dispatches to
15-
# update-dependencies.py.
14+
# Fails if the input file is named "bad.swift" or "crash.swift"; otherwise
15+
# dispatches to update-dependencies.py. "crash.swift" gives an exit code
16+
# other than 1.
1617
#
1718
# ----------------------------------------------------------------------------
1819

1920
from __future__ import print_function
2021

2122
import os
23+
import shutil
2224
import sys
2325

2426
assert sys.argv[1] == '-frontend'
2527

2628
primaryFile = sys.argv[sys.argv.index('-primary-file') + 1]
2729

28-
if os.path.basename(primaryFile) == 'bad.swift':
30+
if (os.path.basename(primaryFile) == 'bad.swift' or
31+
os.path.basename(primaryFile) == 'crash.swift'):
2932
print("Handled", os.path.basename(primaryFile))
30-
sys.exit(1)
33+
34+
# Replace the dependencies file with the input file.
35+
try:
36+
depsFile = sys.argv[sys.argv.index(
37+
'-emit-reference-dependencies-path') + 1]
38+
shutil.copyfile(primaryFile, depsFile)
39+
except ValueError:
40+
pass
41+
42+
if os.path.basename(primaryFile) == 'bad.swift':
43+
sys.exit(1)
44+
else:
45+
sys.exit(129)
3146

3247
dir = os.path.dirname(os.path.abspath(__file__))
3348
execfile(os.path.join(dir, "update-dependencies.py"))
Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// RUN: rm -rf %t && cp -r %S/Inputs/bindings-build-record/ %t
22
// RUN: touch -t 201401240005 %t/*
33

4-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
4+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-INITIAL
55

6-
// MUST-EXEC-NOT: warning
7-
// MUST-EXEC: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
8-
// MUST-EXEC: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
9-
// MUST-EXEC: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
6+
// MUST-EXEC-INITIAL-NOT: warning
7+
// MUST-EXEC-INITIAL: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
8+
// MUST-EXEC-INITIAL: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
9+
// MUST-EXEC-INITIAL: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
10+
11+
// MUST-EXEC-ALL-NOT: warning
12+
// MUST-EXEC-ALL: inputs: ["./main.swift"], output: {{[{].*[}]$}}
13+
// MUST-EXEC-ALL: inputs: ["./other.swift"], output: {{[{].*[}]$}}
14+
// MUST-EXEC-ALL: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}}
1015

1116
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json
1217
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
@@ -19,28 +24,28 @@
1924
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings -serialize-diagnostics ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
2025
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
2126

22-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
27+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL
2328
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json
2429
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
2530
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -O -serialize-diagnostics -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
2631

27-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
32+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL
2833
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json
2934
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -Onone -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
3035

31-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
36+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL
3237
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json
3338
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
3439

35-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
40+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL
3641
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json
3742
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
3843

39-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
44+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL
4045
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json
4146
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -I/ -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
4247

43-
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
48+
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC-ALL
4449
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path %S/Inputs/update-dependencies.py ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json
4550
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -I. -DDEBUG -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC
4651
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -DDEBUG -I. -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=NO-EXEC

test/Driver/Dependencies/bindings-build-record.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@
3737

3838
// RUN: %S/Inputs/touch.py 443865900 %t/*
3939
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=FILE-REMOVED
40-
// FILE-REMOVED: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
41-
// FILE-REMOVED: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
40+
// FILE-REMOVED: inputs: ["./main.swift"], output: {{[{].*[}]$}}
41+
// FILE-REMOVED: inputs: ["./other.swift"], output: {{[{].*[}]$}}
4242
// FILE-REMOVED-NOT: yet-another.swift
4343

4444

4545
// RUN: echo '{version: "bogus", inputs: {"./main.swift": [443865900, 0], "./other.swift": !private [443865900, 0], "./yet-another.swift": !dirty [443865900, 0]}}' > %t/main~buildrecord.swiftdeps
46-
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC
46+
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=INVALID-RECORD
47+
48+
// INVALID-RECORD-NOT: warning
49+
// INVALID-RECORD: inputs: ["./main.swift"], output: {{[{].*[}]$}}
50+
// INVALID-RECORD: inputs: ["./other.swift"], output: {{[{].*[}]$}}
51+
// INVALID-RECORD: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}}

0 commit comments

Comments
 (0)