xref: /openbsd-src/gnu/llvm/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1=====================================
2Cross Translation Unit (CTU) Analysis
3=====================================
4
5Normally, static analysis works in the boundary of one translation unit (TU).
6However, with additional steps and configuration we can enable the analysis to inline the definition of a function from another TU.
7
8.. contents::
9   :local:
10
11Manual CTU Analysis
12-------------------
13
14Let's consider these source files in our minimal example:
15
16.. code-block:: cpp
17
18  // main.cpp
19  int foo();
20
21  int main() {
22    return 3 / foo();
23  }
24
25.. code-block:: cpp
26
27  // foo.cpp
28  int foo() {
29    return 0;
30  }
31
32And a compilation database:
33
34.. code-block:: bash
35
36  [
37    {
38      "directory": "/path/to/your/project",
39      "command": "clang++ -c foo.cpp -o foo.o",
40      "file": "foo.cpp"
41    },
42    {
43      "directory": "/path/to/your/project",
44      "command": "clang++ -c main.cpp -o main.o",
45      "file": "main.cpp"
46    }
47  ]
48
49We'd like to analyze `main.cpp` and discover the division by zero bug.
50In order to be able to inline the definition of `foo` from `foo.cpp` first we have to generate the `AST` (or `PCH`) file of `foo.cpp`:
51
52.. code-block:: bash
53
54  $ pwd $ /path/to/your/project
55  $ clang++ -emit-ast -o foo.cpp.ast foo.cpp
56  $ # Check that the .ast file is generated:
57  $ ls
58  compile_commands.json  foo.cpp.ast  foo.cpp  main.cpp
59  $
60
61The next step is to create a CTU index file which holds the `USR` name and location of external definitions in the source files:
62
63.. code-block:: bash
64
65  $ clang-extdef-mapping -p . foo.cpp
66  c:@F@foo# /path/to/your/project/foo.cpp
67  $ clang-extdef-mapping -p . foo.cpp > externalDefMap.txt
68
69We have to modify `externalDefMap.txt` to contain the name of the `.ast` files instead of the source files:
70
71.. code-block:: bash
72
73  $ sed -i -e "s/.cpp/.cpp.ast/g" externalDefMap.txt
74
75We still have to further modify the `externalDefMap.txt` file to contain relative paths:
76
77.. code-block:: bash
78
79  $ sed -i -e "s|$(pwd)/||g" externalDefMap.txt
80
81Now everything is available for the CTU analysis.
82We have to feed Clang with CTU specific extra arguments:
83
84.. code-block:: bash
85
86  $ pwd
87  /path/to/your/project
88  $ clang++ --analyze -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang ctu-dir=. -Xclang -analyzer-output=plist-multi-file main.cpp
89  main.cpp:5:12: warning: Division by zero
90    return 3 / foo();
91           ~~^~~~~~~
92  1 warning generated.
93  $ # The plist file with the result is generated.
94  $ ls
95  compile_commands.json  externalDefMap.txt  foo.ast  foo.cpp  foo.cpp.ast  main.cpp  main.plist
96  $
97
98This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use `CodeChecker` or `scan-build-py`.
99
100Automated CTU Analysis with CodeChecker
101---------------------------------------
102The `CodeChecker <https://github.com/Ericsson/codechecker>`_ project fully supports automated CTU analysis with Clang.
103Once we have set up the `PATH` environment variable and we activated the python `venv` then it is all it takes:
104
105.. code-block:: bash
106
107  $ CodeChecker analyze --ctu compile_commands.json -o reports
108  [INFO 2019-07-16 17:21] - Pre-analysis started.
109  [INFO 2019-07-16 17:21] - Collecting data for ctu analysis.
110  [INFO 2019-07-16 17:21] - [1/2] foo.cpp
111  [INFO 2019-07-16 17:21] - [2/2] main.cpp
112  [INFO 2019-07-16 17:21] - Pre-analysis finished.
113  [INFO 2019-07-16 17:21] - Starting static analysis ...
114  [INFO 2019-07-16 17:21] - [1/2] clangsa analyzed foo.cpp successfully.
115  [INFO 2019-07-16 17:21] - [2/2] clangsa analyzed main.cpp successfully.
116  [INFO 2019-07-16 17:21] - ----==== Summary ====----
117  [INFO 2019-07-16 17:21] - Successfully analyzed
118  [INFO 2019-07-16 17:21] -   clangsa: 2
119  [INFO 2019-07-16 17:21] - Total analyzed compilation commands: 2
120  [INFO 2019-07-16 17:21] - ----=================----
121  [INFO 2019-07-16 17:21] - Analysis finished.
122  [INFO 2019-07-16 17:21] - To view results in the terminal use the "CodeChecker parse" command.
123  [INFO 2019-07-16 17:21] - To store results use the "CodeChecker store" command.
124  [INFO 2019-07-16 17:21] - See --help and the user guide for further options about parsing and storing the reports.
125  [INFO 2019-07-16 17:21] - ----=================----
126  [INFO 2019-07-16 17:21] - Analysis length: 0.659618854523 sec.
127  $ ls
128  compile_commands.json  foo.cpp  foo.cpp.ast  main.cpp  reports
129  $ tree reports
130  reports
131  ├── compile_cmd.json
132  ├── compiler_info.json
133  ├── foo.cpp_53f6fbf7ab7ec9931301524b551959e2.plist
134  ├── main.cpp_23db3d8df52ff0812e6e5a03071c8337.plist
135  ├── metadata.json
136  └── unique_compile_commands.json
137
138  0 directories, 6 files
139  $
140
141The `plist` files contain the results of the analysis, which may be viewed with the regular analysis tools.
142E.g. one may use `CodeChecker parse` to view the results in command line:
143
144.. code-block:: bash
145
146  $ CodeChecker parse reports
147  [HIGH] /home/egbomrt/ctu_mini_raw_project/main.cpp:5:12: Division by zero [core.DivideZero]
148    return 3 / foo();
149             ^
150
151  Found 1 defect(s) in main.cpp
152
153
154  ----==== Summary ====----
155  -----------------------
156  Filename | Report count
157  -----------------------
158  main.cpp |            1
159  -----------------------
160  -----------------------
161  Severity | Report count
162  -----------------------
163  HIGH     |            1
164  -----------------------
165  ----=================----
166  Total number of reports: 1
167  ----=================----
168
169Or we can use `CodeChecker parse -e html` to export the results into HTML format:
170
171.. code-block:: bash
172
173  $ CodeChecker parse -e html -o html_out reports
174  $ firefox html_out/index.html
175
176Automated CTU Analysis with scan-build-py (don't do it)
177-------------------------------------------------------
178We actively develop CTU with CodeChecker as a "runner" script, `scan-build-py` is not actively developed for CTU.
179`scan-build-py` has various errors and issues, expect it to work with the very basic projects only.
180
181Example usage of scan-build-py:
182
183.. code-block:: bash
184
185  $ /your/path/to/llvm-project/clang/tools/scan-build-py/bin/analyze-build --ctu
186  analyze-build: Run 'scan-view /tmp/scan-build-2019-07-17-17-53-33-810365-7fqgWk' to examine bug reports.
187  $ /your/path/to/llvm-project/clang/tools/scan-view/bin/scan-view /tmp/scan-build-2019-07-17-17-53-33-810365-7fqgWk
188  Starting scan-view at: http://127.0.0.1:8181
189    Use Ctrl-C to exit.
190  [6336:6431:0717/175357.633914:ERROR:browser_process_sub_thread.cc(209)] Waited 5 ms for network service
191  Opening in existing browser session.
192  ^C
193  $
194