Skip to content

Commit 601c9c5

Browse files
committed
[clang][deps] Ensure reported context hash is strict
One of main goals of the dependency scanner is to be strict about module compatibility. This is achieved through strict context hash. This patch ensures that strict context hash is enabled not only during the scan itself (and its minimized implicit build), but also when actually reporting the dependency. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D111720
1 parent 9278dd1 commit 601c9c5

File tree

8 files changed

+112
-0
lines changed

8 files changed

+112
-0
lines changed

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ CompilerInvocation ModuleDepCollector::makeInvocationForModuleBuildWithoutPaths(
5656

5757
Optimize(CI);
5858

59+
// The original invocation probably didn't have strict context hash enabled.
60+
// We will use the context hash of this invocation to distinguish between
61+
// multiple incompatible versions of the same module and will use it when
62+
// reporting dependencies to the clients. Let's make sure we're using
63+
// **strict** context hash in order to prevent accidental sharing of
64+
// incompatible modules (e.g. with differences in search paths).
65+
CI.getHeaderSearchOpts().ModulesStrictContextHash = true;
66+
5967
return CI;
6068
}
6169

clang/test/ClangScanDeps/Inputs/modules-context-hash/a/dep.h

Whitespace-only changes.

clang/test/ClangScanDeps/Inputs/modules-context-hash/b/dep.h

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"directory": "DIR",
4+
"command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -IDIR/a -o DIR/tu_a.o",
5+
"file": "DIR/tu.c"
6+
},
7+
{
8+
"directory": "DIR",
9+
"command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -IDIR/b -o DIR/tu_b.o",
10+
"file": "DIR/tu.c"
11+
}
12+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "dep.h"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module mod { header "mod.h" }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "mod.h"
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// RUN: rm -rf %t && mkdir %t
2+
// RUN: cp -r %S/Inputs/modules-context-hash/* %t
3+
4+
// Check that the scanner reports the same module as distinct dependencies when
5+
// a single translation unit gets compiled with multiple command-lines that
6+
// produce different **strict** context hashes.
7+
8+
// RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-context-hash/cdb.json.template > %t/cdb.json
9+
// RUN: echo -%t > %t/result.json
10+
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -j 1 >> %t/result.json
11+
// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck %s -check-prefix=CHECK
12+
13+
// CHECK: -[[PREFIX:.*]]
14+
// CHECK-NEXT: {
15+
// CHECK-NEXT: "modules": [
16+
// CHECK-NEXT: {
17+
// CHECK-NEXT: "clang-module-deps": [],
18+
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
19+
// CHECK-NEXT: "command-line": [
20+
// CHECK-NEXT: "-cc1"
21+
// CHECK: "-emit-module"
22+
// CHECK: "-I"
23+
// CHECK: "[[PREFIX]]/a"
24+
// CHECK: "-fmodule-name=mod"
25+
// CHECK: ],
26+
// CHECK-NEXT: "context-hash": "[[HASH_MOD_A:.*]]",
27+
// CHECK-NEXT: "file-deps": [
28+
// CHECK-NEXT: "[[PREFIX]]/a/dep.h",
29+
// CHECK-NEXT: "[[PREFIX]]/mod.h",
30+
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
31+
// CHECK-NEXT: ],
32+
// CHECK-NEXT: "name": "mod"
33+
// CHECK-NEXT: },
34+
// CHECK-NEXT: {
35+
// CHECK-NEXT: "clang-module-deps": [],
36+
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
37+
// CHECK-NEXT: "command-line": [
38+
// CHECK-NEXT: "-cc1"
39+
// CHECK: "-emit-module"
40+
// CHECK: "-I"
41+
// CHECK: "[[PREFIX]]/b"
42+
// CHECK: "-fmodule-name=mod"
43+
// CHECK: ],
44+
// CHECK-NEXT: "context-hash": "[[HASH_MOD_B:.*]]",
45+
// CHECK-NEXT: "file-deps": [
46+
// CHECK-NEXT: "[[PREFIX]]/b/dep.h",
47+
// CHECK-NEXT: "[[PREFIX]]/mod.h",
48+
// CHECK-NEXT: "[[PREFIX]]/module.modulemap"
49+
// CHECK-NEXT: ],
50+
// CHECK-NEXT: "name": "mod"
51+
// CHECK-NEXT: }
52+
// CHECK-NEXT: ],
53+
// CHECK-NEXT: "translation-units": [
54+
// CHECK-NEXT: {
55+
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
56+
// CHECK-NEXT: "clang-module-deps": [
57+
// CHECK-NEXT: {
58+
// CHECK-NEXT: "context-hash": "[[HASH_MOD_A]]",
59+
// CHECK-NEXT: "module-name": "mod"
60+
// CHECK-NEXT: }
61+
// CHECK-NEXT: ],
62+
// CHECK-NEXT: "command-line": [
63+
// CHECK-NEXT: "-fno-implicit-modules",
64+
// CHECK-NEXT: "-fno-implicit-module-maps"
65+
// CHECK-NEXT: ],
66+
// CHECK-NEXT: "file-deps": [
67+
// CHECK-NEXT: "[[PREFIX]]/tu.c"
68+
// CHECK-NEXT: ],
69+
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c"
70+
// CHECK-NEXT: },
71+
// CHECK-NEXT: {
72+
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
73+
// CHECK-NEXT: "clang-module-deps": [
74+
// CHECK-NEXT: {
75+
// CHECK-NEXT: "context-hash": "[[HASH_MOD_B]]",
76+
// CHECK-NEXT: "module-name": "mod"
77+
// CHECK-NEXT: }
78+
// CHECK-NEXT: ],
79+
// CHECK-NEXT: "command-line": [
80+
// CHECK-NEXT: "-fno-implicit-modules",
81+
// CHECK-NEXT: "-fno-implicit-module-maps"
82+
// CHECK-NEXT: ],
83+
// CHECK-NEXT: "file-deps": [
84+
// CHECK-NEXT: "[[PREFIX]]/tu.c"
85+
// CHECK-NEXT: ],
86+
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c"
87+
// CHECK-NEXT: }
88+
// CHECK-NEXT: ]
89+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)