Skip to content

Commit dfdee9a

Browse files
jansvoboda11c-rhodes
authored andcommitted
[clang][modules] Derive mtime from PCM timestamps, not PCM files (llvm#162965)
llvm#137363 was supposed to be NFC for the `CrossProcessModuleCache` (a.k.a normal implicit module builds), but accidentally passed the wrong path to `sys::fs::status`. Then, llvm#141358 removed the correct path that should've been passed instead. (The variable was flagged as unused.) None of our existing tests caught this regression, we only found out due to a SourceKit-LSP benchmark getting slower. This PR re-implements the original behavior, adds new remark to Clang for PCM input file validation, and uses it to create more reliable tests of the `-fmodules-validate-once-per-build-session` flag. (cherry picked from commit ce8abef)
1 parent bd9bc53 commit dfdee9a

File tree

5 files changed

+137
-111
lines changed

5 files changed

+137
-111
lines changed

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ def MissingFieldInitializers : DiagGroup<"missing-field-initializers",
624624
def ModuleLock : DiagGroup<"module-lock">;
625625
def ModuleBuild : DiagGroup<"module-build">;
626626
def ModuleImport : DiagGroup<"module-import">;
627+
def ModuleValidation : DiagGroup<"module-validation">;
627628
def ModuleConflict : DiagGroup<"module-conflict">;
628629
def ModuleFileExtension : DiagGroup<"module-file-extension">;
629630
def ModuleIncludeDirectiveTranslation : DiagGroup<"module-include-translation">;

clang/include/clang/Basic/DiagnosticSerializationKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ def remark_module_import : Remark<
8282
"importing module '%0'%select{| into '%3'}2 from '%1'">,
8383
ShowInSystemHeader,
8484
InGroup<ModuleImport>;
85+
def remark_module_validation : Remark<
86+
"validating %0 input files in module '%1' from '%2'">,
87+
ShowInSystemHeader,
88+
InGroup<ModuleValidation>;
8589

8690
def err_imported_module_not_found : Error<
8791
"module '%0' in precompiled file '%1' %select{(imported by precompiled file '%2') |}4"

clang/lib/Serialization/ASTReader.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,6 +3103,10 @@ ASTReader::ReadControlBlock(ModuleFile &F,
31033103
F.Kind == MK_ImplicitModule)
31043104
N = ForceValidateUserInputs ? NumUserInputs : 0;
31053105

3106+
if (N != 0)
3107+
Diag(diag::remark_module_validation)
3108+
<< N << F.ModuleName << F.FileName;
3109+
31063110
for (unsigned I = 0; I < N; ++I) {
31073111
InputFile IF = getInputFile(F, I+1, Complain);
31083112
if (!IF.getFile() || IF.isOutOfDate())

clang/lib/Serialization/ModuleCache.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ class CrossProcessModuleCache : public ModuleCache {
3434
}
3535

3636
std::time_t getModuleTimestamp(StringRef ModuleFilename) override {
37+
std::string TimestampFilename =
38+
serialization::ModuleFile::getTimestampFilename(ModuleFilename);
3739
llvm::sys::fs::file_status Status;
38-
if (llvm::sys::fs::status(ModuleFilename, Status) != std::error_code{})
40+
if (llvm::sys::fs::status(TimestampFilename, Status) != std::error_code{})
3941
return 0;
4042
return llvm::sys::toTimeT(Status.getLastModificationTime());
4143
}
Lines changed: 125 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,134 @@
1-
#include "foo.h"
2-
#include "bar.h"
3-
4-
// Clear the module cache.
5-
// RUN: rm -rf %t
6-
// RUN: mkdir -p %t/Inputs
7-
// RUN: mkdir -p %t/modules-to-compare
1+
// This tests the behavior of -fmodules-validate-once-per-build-session with
2+
// different combinations of flags and states of the module cache.
83

9-
// ===
10-
// Create a module. We will use -I or -isystem to determine whether to treat
11-
// foo.h as a system header.
12-
// RUN: echo 'void meow(void);' > %t/Inputs/foo.h
13-
// RUN: echo 'void woof(void);' > %t/Inputs/bar.h
14-
// RUN: echo 'module Foo { header "foo.h" }' > %t/Inputs/module.modulemap
15-
// RUN: echo 'extern module Bar "bar.modulemap"' >> %t/Inputs/module.modulemap
16-
// RUN: echo 'module Bar { header "bar.h" }' > %t/Inputs/bar.modulemap
4+
// Note: The `sleep 1` commands sprinkled throughout this test make the strict
5+
// comparisons of epoch mtimes work as expected. Some may be unnecessary,
6+
// but make the intent clearer.
177

18-
// ===
19-
// Compile the module.
20-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
21-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
22-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user-no-force -fsyntax-only -I %t/Inputs -fno-modules-force-validate-user-headers -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
23-
// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
24-
// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
25-
// RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
26-
// RUN: ls -R %t/modules-cache-user | grep Bar.pcm.timestamp
27-
// RUN: ls -R %t/modules-cache-user-no-force | grep Foo.pcm.timestamp
28-
// RUN: ls -R %t/modules-cache-user-no-force | grep Bar.pcm.timestamp
29-
// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-before.pcm
30-
// RUN: cp %t/modules-cache/Bar.pcm %t/modules-to-compare/Bar-before.pcm
31-
// RUN: cp %t/modules-cache-user/Foo.pcm %t/modules-to-compare/Foo-before-user.pcm
32-
// RUN: cp %t/modules-cache-user/Bar.pcm %t/modules-to-compare/Bar-before-user.pcm
33-
// RUN: cp %t/modules-cache-user-no-force/Foo.pcm %t/modules-to-compare/Foo-before-user-no-force.pcm
34-
// RUN: cp %t/modules-cache-user-no-force/Bar.pcm %t/modules-to-compare/Bar-before-user-no-force.pcm
35-
36-
// ===
37-
// Use it, and make sure that we did not recompile it.
38-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
39-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
40-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-use-no-force -fsyntax-only -I %t/Inputs -fno-modules-force-validate-user-headers -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
41-
// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
42-
// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
43-
// RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
44-
// RUN: ls -R %t/modules-cache-user | grep Bar.pcm.timestamp
45-
// RUN: ls -R %t/modules-cache-user-no-force | grep Foo.pcm.timestamp
46-
// RUN: ls -R %t/modules-cache-user-no-force | grep Bar.pcm.timestamp
47-
// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
48-
// RUN: cp %t/modules-cache/Bar.pcm %t/modules-to-compare/Bar-after.pcm
49-
// RUN: cp %t/modules-cache-user/Foo.pcm %t/modules-to-compare/Foo-after-user.pcm
50-
// RUN: cp %t/modules-cache-user/Bar.pcm %t/modules-to-compare/Bar-after-user.pcm
51-
// RUN: cp %t/modules-cache-user-no-force/Foo.pcm %t/modules-to-compare/Foo-after-user-no-force.pcm
52-
// RUN: cp %t/modules-cache-user-no-force/Bar.pcm %t/modules-to-compare/Bar-after-user-no-force.pcm
8+
// RUN: rm -rf %t
9+
// RUN: split-file %s %t
10+
// RUN: echo "-fsyntax-only -fmodules -fmodules-cache-path=%/t/module-cache" > %t/ctx.rsp
11+
// RUN: echo "-fbuild-session-file=%/t/module-cache/session.timestamp" >> %t/ctx.rsp
12+
// RUN: echo "-fmodules-validate-once-per-build-session" >> %t/ctx.rsp
13+
// RUN: echo "-Rmodule-build -Rmodule-validation" >> %t/ctx.rsp
5314

54-
// RUN: diff %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
55-
// RUN: diff %t/modules-to-compare/Bar-before.pcm %t/modules-to-compare/Bar-after.pcm
56-
// RUN: diff %t/modules-to-compare/Foo-before-user.pcm %t/modules-to-compare/Foo-after-user.pcm
57-
// RUN: diff %t/modules-to-compare/Bar-before-user.pcm %t/modules-to-compare/Bar-after-user.pcm
58-
// RUN: diff %t/modules-to-compare/Foo-before-user-no-force.pcm %t/modules-to-compare/Foo-after-user-no-force.pcm
59-
// RUN: diff %t/modules-to-compare/Bar-before-user-no-force.pcm %t/modules-to-compare/Bar-after-user-no-force.pcm
15+
//--- include/foo.h
16+
//--- include/module.modulemap
17+
module Foo { header "foo.h" }
6018

61-
// ===
62-
// Change the sources.
19+
//--- clean.c
20+
// Clean module cache. Modules will get compiled regardless of validation settings.
21+
// RUN: mkdir %t/module-cache
6322
// RUN: sleep 1
64-
// RUN: echo 'void meow2(void);' > %t/Inputs/foo.h
65-
// RUN: echo 'module Bar { header "bar.h" export * }' > %t/Inputs/bar.modulemap
23+
// RUN: touch %t/module-cache/session.timestamp
24+
// RUN: sleep 1
25+
// RUN: %clang @%t/ctx.rsp %t/clean.c -DCTX=1 \
26+
// RUN: -isystem %t/include -fmodules-validate-system-headers \
27+
// RUN: 2>&1 | FileCheck %t/clean.c
28+
// RUN: %clang @%t/ctx.rsp %t/clean.c -DCTX=2 \
29+
// RUN: -I %t/include -fmodules-validate-system-headers \
30+
// RUN: 2>&1 | FileCheck %t/clean.c
31+
// RUN: %clang @%t/ctx.rsp %t/clean.c -DCTX=3 \
32+
// RUN: -I %t/include -fmodules-validate-system-headers -Xclang -fno-modules-force-validate-user-headers \
33+
// RUN: 2>&1 | FileCheck %t/clean.c
34+
#include "foo.h"
35+
// CHECK: building module 'Foo'
6636

67-
// ===
68-
// Use the module, and make sure that we did not recompile it if foo.h or
69-
// module.modulemap are system files or user files with force validation disabled,
70-
// even though the sources changed.
71-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
72-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
73-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user-no-force -fsyntax-only -I %t/Inputs -fno-modules-force-validate-user-headers -fmodules-validate-system-headers -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
74-
// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
75-
// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
76-
// RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
77-
// RUN: ls -R %t/modules-cache-user | grep Bar.pcm.timestamp
78-
// RUN: ls -R %t/modules-cache-user-no-force | grep Foo.pcm.timestamp
79-
// RUN: ls -R %t/modules-cache-user-no-force | grep Bar.pcm.timestamp
80-
// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
81-
// RUN: cp %t/modules-cache/Bar.pcm %t/modules-to-compare/Bar-after.pcm
82-
// RUN: cp %t/modules-cache-user/Foo.pcm %t/modules-to-compare/Foo-after-user.pcm
83-
// RUN: cp %t/modules-cache-user/Bar.pcm %t/modules-to-compare/Bar-after-user.pcm
84-
// RUN: cp %t/modules-cache-user-no-force/Foo.pcm %t/modules-to-compare/Foo-after-user-no-force.pcm
85-
// RUN: cp %t/modules-cache-user-no-force/Bar.pcm %t/modules-to-compare/Bar-after-user-no-force.pcm
37+
//--- no-change-same-session.c
38+
// Populated module cache in the same build session with unchanged inputs.
39+
// Validation only happens when it's forced for user headers. No compiles.
40+
// RUN: sleep 1
41+
// RUN: %clang @%t/ctx.rsp %t/no-change-same-session.c -DCTX=1 \
42+
// RUN: -isystem %t/include -fmodules-validate-system-headers \
43+
// RUN: 2>&1 | FileCheck %t/no-change-same-session.c --check-prefix=CHECK-NO-VALIDATION-OR-BUILD --allow-empty
44+
// RUN: %clang @%t/ctx.rsp %t/no-change-same-session.c -DCTX=2 \
45+
// RUN: -I %t/include -fmodules-validate-system-headers \
46+
// RUN: 2>&1 | FileCheck %t/no-change-same-session.c --check-prefix=CHECK-VALIDATION-ONLY
47+
// RUN: %clang @%t/ctx.rsp %t/no-change-same-session.c -DCTX=3 \
48+
// RUN: -I %t/include -fmodules-validate-system-headers -Xclang -fno-modules-force-validate-user-headers \
49+
// RUN: 2>&1 | FileCheck %t/no-change-same-session.c --check-prefix=CHECK-NO-VALIDATION-OR-BUILD --allow-empty
50+
#include "foo.h"
51+
// CHECK-NO-VALIDATION-OR-BUILD-NOT: validating {{[0-9]+}} input files in module 'Foo'
52+
// CHECK-NO-VALIDATION-OR-BUILD-NOT: building module 'Foo'
53+
// CHECK-VALIDATION-ONLY: validating {{[0-9]+}} input files in module 'Foo'
54+
// CHECK-VALIDATION-ONLY-NOT: building module 'Foo'
8655

87-
// RUN: diff %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
88-
// RUN: diff %t/modules-to-compare/Bar-before.pcm %t/modules-to-compare/Bar-after.pcm
89-
// When foo.h is an user header, we will validate it by default.
90-
// RUN: not diff %t/modules-to-compare/Foo-before-user.pcm %t/modules-to-compare/Foo-after-user.pcm
91-
// RUN: not diff %t/modules-to-compare/Bar-before-user.pcm %t/modules-to-compare/Bar-after-user.pcm
92-
// When foo.h is an user header, we will not validate it if force validation is turned off.
93-
// RUN: diff %t/modules-to-compare/Foo-before-user-no-force.pcm %t/modules-to-compare/Foo-after-user-no-force.pcm
94-
// RUN: diff %t/modules-to-compare/Bar-before-user-no-force.pcm %t/modules-to-compare/Bar-after-user-no-force.pcm
56+
//--- change-same-session.c
57+
// Populated module cache in the same build session with changed inputs.
58+
// Validation only happens when it's forced for user headers and results in compilation.
59+
// RUN: sleep 1
60+
// RUN: touch %t/include/foo.h
61+
// RUN: sleep 1
62+
// RUN: %clang @%t/ctx.rsp %t/change-same-session.c -DCTX=1 \
63+
// RUN: -isystem %t/include -fmodules-validate-system-headers \
64+
// RUN: 2>&1 | FileCheck %t/change-same-session.c --check-prefix=CHECK-NO-VALIDATION-OR-BUILD --allow-empty
65+
// RUN: %clang @%t/ctx.rsp %t/change-same-session.c -DCTX=2 \
66+
// RUN: -I %t/include -fmodules-validate-system-headers \
67+
// RUN: 2>&1 | FileCheck %t/change-same-session.c --check-prefix=CHECK-VALIDATION-AND-BUILD
68+
// RUN: %clang @%t/ctx.rsp %t/change-same-session.c -DCTX=3 \
69+
// RUN: -I %t/include -fmodules-validate-system-headers -Xclang -fno-modules-force-validate-user-headers \
70+
// RUN: 2>&1 | FileCheck %t/change-same-session.c --check-prefix=CHECK-NO-VALIDATION-OR-BUILD --allow-empty
71+
#include "foo.h"
72+
// CHECK-NO-VALIDATION-OR-BUILD-NOT: validating {{[0-9]+}} input files in module 'Foo'
73+
// CHECK-NO-VALIDATION-OR-BUILD-NOT: building module 'Foo'
74+
// CHECK-VALIDATION-AND-BUILD: validating {{[0-9]+}} input files in module 'Foo'
75+
// CHECK-VALIDATION-AND-BUILD: building module 'Foo'
9576

96-
// ===
97-
// Recompile the module if the today's date is before 01 January 2100.
98-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
99-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
100-
// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t/modules-cache-user-no-force -fsyntax-only -I %t/Inputs -fno-modules-force-validate-user-headers -fmodules-validate-system-headers -fbuild-session-timestamp=4102441200 -fmodules-validate-once-per-build-session %s
101-
// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
102-
// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
103-
// RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
104-
// RUN: ls -R %t/modules-cache-user | grep Bar.pcm.timestamp
105-
// RUN: ls -R %t/modules-cache-user-no-force | grep Foo.pcm.timestamp
106-
// RUN: ls -R %t/modules-cache-user-no-force | grep Bar.pcm.timestamp
107-
// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
108-
// RUN: cp %t/modules-cache/Bar.pcm %t/modules-to-compare/Bar-after.pcm
109-
// RUN: cp %t/modules-cache-user/Foo.pcm %t/modules-to-compare/Foo-after-user.pcm
110-
// RUN: cp %t/modules-cache-user/Bar.pcm %t/modules-to-compare/Bar-after-user.pcm
111-
// RUN: cp %t/modules-cache-user-no-force/Foo.pcm %t/modules-to-compare/Foo-after-user-no-force.pcm
112-
// RUN: cp %t/modules-cache-user-no-force/Bar.pcm %t/modules-to-compare/Bar-after-user-no-force.pcm
77+
//--- change-new-session.c
78+
// Populated module cache in a new build session with changed inputs.
79+
// All configurations validate and recompile.
80+
// RUN: sleep 1
81+
// RUN: touch %t/include/foo.h
82+
// RUN: sleep 1
83+
// RUN: touch %t/module-cache/session.timestamp
84+
// RUN: sleep 1
85+
// RUN: %clang @%t/ctx.rsp %t/change-new-session.c -DCTX=1 \
86+
// RUN: -isystem %t/include -fmodules-validate-system-headers \
87+
// RUN: 2>&1 | FileCheck %t/change-new-session.c --check-prefixes=CHECK,CHECK-VALIDATE-ONCE
88+
// NOTE: Forced user headers validation causes redundant validation of the just-built module.
89+
// RUN: %clang @%t/ctx.rsp %t/change-new-session.c -DCTX=2 \
90+
// RUN: -I %t/include -fmodules-validate-system-headers \
91+
// RUN: 2>&1 | FileCheck %t/change-new-session.c --check-prefixes=CHECK,CHECK-FORCE-VALIDATE-TWICE
92+
// RUN: %clang @%t/ctx.rsp %t/change-new-session.c -DCTX=3 \
93+
// RUN: -I %t/include -fmodules-validate-system-headers -Xclang -fno-modules-force-validate-user-headers \
94+
// RUN: 2>&1 | FileCheck %t/change-new-session.c --check-prefixes=CHECK,CHECK-VALIDATE-ONCE
95+
#include "foo.h"
96+
// CHECK: validating {{[0-9]+}} input files in module 'Foo'
97+
// CHECK: building module 'Foo'
98+
// CHECK-VALIDATE-ONCE-NOT: validating {{[0-9]+}} input files in module 'Foo'
99+
// CHECK-FORCE-VALIDATE-TWICE: validating {{[0-9]+}} input files in module 'Foo'
113100

114-
// RUN: not diff %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
115-
// RUN: not diff %t/modules-to-compare/Bar-before.pcm %t/modules-to-compare/Bar-after.pcm
116-
// RUN: not diff %t/modules-to-compare/Foo-before-user.pcm %t/modules-to-compare/Foo-after-user.pcm
117-
// RUN: not diff %t/modules-to-compare/Bar-before-user.pcm %t/modules-to-compare/Bar-after-user.pcm
118-
// RUN: not diff %t/modules-to-compare/Foo-before-user-no-force.pcm %t/modules-to-compare/Foo-after-user-no-force.pcm
119-
// RUN: not diff %t/modules-to-compare/Bar-before-user-no-force.pcm %t/modules-to-compare/Bar-after-user-no-force.pcm
101+
//--- no-change-new-session-twice.c
102+
// Populated module cache in a new build session with unchanged inputs.
103+
// At first, all configurations validate but don't recompile.
104+
// RUN: sleep 1
105+
// RUN: touch %t/module-cache/session.timestamp
106+
// RUN: sleep 1
107+
// RUN: %clang @%t/ctx.rsp %t/no-change-new-session-twice.c -DCTX=1 \
108+
// RUN: -isystem %t/include -fmodules-validate-system-headers \
109+
// RUN: 2>&1 | FileCheck %t/no-change-new-session-twice.c --check-prefix=CHECK-ONCE
110+
// RUN: %clang @%t/ctx.rsp %t/no-change-new-session-twice.c -DCTX=2 \
111+
// RUN: -I %t/include -fmodules-validate-system-headers \
112+
// RUN: 2>&1 | FileCheck %t/no-change-new-session-twice.c --check-prefix=CHECK-ONCE
113+
// RUN: %clang @%t/ctx.rsp %t/no-change-new-session-twice.c -DCTX=3 \
114+
// RUN: -I %t/include -fmodules-validate-system-headers -Xclang -fno-modules-force-validate-user-headers \
115+
// RUN: 2>&1 | FileCheck %t/no-change-new-session-twice.c --check-prefix=CHECK-ONCE
116+
//
117+
// Then, only the forced user header validation performs redundant validation (but no compilation).
118+
// All other configurations do not validate and do not compile.
119+
// RUN: sleep 1
120+
// RUN: %clang @%t/ctx.rsp %t/no-change-new-session-twice.c -DCTX=1 \
121+
// RUN: -isystem %t/include -fmodules-validate-system-headers \
122+
// RUN: 2>&1 | FileCheck %t/no-change-new-session-twice.c --check-prefix=CHECK-NOT-TWICE --allow-empty
123+
// NOTE: Forced user headers validation causes redundant validation of the just-validated module.
124+
// RUN: %clang @%t/ctx.rsp %t/no-change-new-session-twice.c -DCTX=2 \
125+
// RUN: -I %t/include -fmodules-validate-system-headers \
126+
// RUN: 2>&1 | FileCheck %t/no-change-new-session-twice.c --check-prefix=CHECK-ONCE
127+
// RUN: %clang @%t/ctx.rsp %t/no-change-new-session-twice.c -DCTX=3 \
128+
// RUN: -I %t/include -fmodules-validate-system-headers -Xclang -fno-modules-force-validate-user-headers \
129+
// RUN: 2>&1 | FileCheck %t/no-change-new-session-twice.c --check-prefix=CHECK-NOT-TWICE --allow-empty
130+
#include "foo.h"
131+
// CHECK-ONCE: validating {{[0-9]+}} input files in module 'Foo'
132+
// CHECK-ONCE-NOT: building module 'Foo'
133+
// CHECK-NOT-TWICE-NOT: validating {{[0-9]+}} input files in module 'Foo'
134+
// CHECK-NOT-TWICE-NOT: building module 'Foo'

0 commit comments

Comments
 (0)