]> git.proxmox.com Git - llvm-toolchain.git/blob - debian/qualify-clang.sh
* Don't use gold on ppc64el. It fails to build in that case
[llvm-toolchain.git] / debian / qualify-clang.sh
1 #!/bin/bash
2 # Stop at the first error
3 set -e
4 if ! test -d debian/; then
5 echo "$0: Could not find the debian/ directory"
6 exit 1
7 fi
8 VERSION=$(dpkg-parsechangelog | sed -rne "s,^Version: 1:([0-9]+).*,\1,p")
9 DETAILED_VERSION=$(dpkg-parsechangelog | sed -rne "s,^Version: 1:([0-9.]+)(~|-)(.*),\1\2\3,p")
10 DEB_HOST_ARCH=$(dpkg-architecture -qDEB_HOST_ARCH)
11
12 LIST="libomp5-${VERSION}_${DETAILED_VERSION}_amd64.deb libomp-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb lldb-${VERSION}_${DETAILED_VERSION}_amd64.deb python3-lldb-${VERSION}_${DETAILED_VERSION}_amd64.deb libllvm${VERSION}_${DETAILED_VERSION}_amd64.deb llvm-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb liblldb-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb libclang1-${VERSION}_${DETAILED_VERSION}_amd64.deb libclang-common-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb llvm-${VERSION}_${DETAILED_VERSION}_amd64.deb liblldb-${VERSION}_${DETAILED_VERSION}_amd64.deb llvm-${VERSION}-runtime_${DETAILED_VERSION}_amd64.deb lld-${VERSION}_${DETAILED_VERSION}_amd64.deb libfuzzer-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb libclang-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb libc++-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb libc++abi-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb libc++1-${VERSION}_${DETAILED_VERSION}_amd64.deb libc++abi1-${VERSION}_${DETAILED_VERSION}_amd64.deb clang-${VERSION}_${DETAILED_VERSION}_amd64.deb llvm-${VERSION}-tools_${DETAILED_VERSION}_amd64.deb clang-tools-${VERSION}_${DETAILED_VERSION}_amd64.deb clangd-${VERSION}_${DETAILED_VERSION}_amd64.deb clang-${VERSION}-dbgsym_${DETAILED_VERSION}_amd64.deb libclang1-${VERSION}-dbgsym_${DETAILED_VERSION}_amd64.deb libclang-cpp${VERSION}_${DETAILED_VERSION}_amd64.deb clang-tidy-${VERSION}_${DETAILED_VERSION}_amd64.deb libclang-cpp${VERSION}-dev_${DETAILED_VERSION}_amd64.deb"
13 echo "To install everything:"
14 echo "sudo apt --purge remove 'libomp5-*' 'libc++*dev' 'libc++*' 'python3-lldb-*'"
15 echo "sudo dpkg -i $LIST"
16 L=""
17 for f in $LIST; do
18 L="$L $(echo $f|cut -d_ -f1)"
19 done
20 echo "or"
21 echo "apt-get install $L"
22
23 if test ! -f /usr/bin/llvm-config-$VERSION; then
24 echo "Install llvm-$VERSION & llvm-$VERSION-dev"
25 exit 1
26 fi
27 if test ! -f /usr/lib/llvm-$VERSION/lib/libLLVM-$VERSION.so; then
28 echo "Install llvm-$VERSION-dev"
29 exit 1
30 fi
31
32 echo "Testing llvm-$VERSION and llvm-$VERSION-dev ..."
33 llvm-config-$VERSION --link-shared --libs &> /dev/null
34
35 if llvm-config-$VERSION --cxxflags | grep " \-W"; then
36 echo "llvm-config should not export -W warnings"
37 exit 1
38 fi
39
40 # Test https://bugs.llvm.org/show_bug.cgi?id=40059
41 nm /usr/lib/llvm-$VERSION/lib/libLLVMBitWriter.a &> foo.log
42 if grep "File format not recognized" foo.log; then
43 echo "nm libLLVMBitWriter.a contains 'File format not recognized'"
44 exit 1
45 fi
46
47 if test ! -f /usr/bin/scan-build-$VERSION; then
48 echo "Install clang-tools-$VERSION"
49 exit 1
50 fi
51 echo "Testing clang-tools-$VERSION ..."
52
53 echo '
54 void test() {
55 int x;
56 x = 1; // warn
57 }
58 '> foo.c
59
60 # Ignore if gcc isn't available
61 scan-build-$VERSION -o scan-build gcc -c foo.c &> /dev/null || true
62 scan-build-$VERSION -o scan-build clang-$VERSION -c foo.c &> /dev/null
63 scan-build-$VERSION --exclude non-existing/ --exclude /tmp/ -v clang-$VERSION -c foo.c &> /dev/null
64 scan-build-$VERSION --exclude $(pwd) -v clang-$VERSION -c foo.c &> foo.log
65 if ! grep -q -E "scan-build: 0 bugs found." foo.log; then
66 echo "scan-build --exclude didn't ignore the defect"
67 exit 42
68 fi
69 rm -rf scan-build
70
71 echo 'namespace mozilla {
72 namespace dom {
73 void foo();
74 }
75 }
76 ' > foo.cpp
77 clang-tidy-$VERSION -checks='modernize-concat-nested-namespaces' foo.cpp -extra-arg=-std=c++17 &> foo.log
78 if ! grep -q "nested namespaces can " foo.log; then
79 echo "Clang-tidy didn't detect the issue"
80 cat foo.log
81 exit 1
82 fi
83
84
85 rm -rf cmaketest && mkdir cmaketest
86 cat > cmaketest/CMakeLists.txt <<EOF
87 cmake_minimum_required(VERSION 2.8.12)
88 project(SanityCheck)
89 add_library(MyLibrary foo.cpp)
90 EOF
91 mkdir cmaketest/standard
92 cp foo.cpp cmaketest/
93 cd cmaketest/standard
94 # run with cmake
95 CXX=clang-$VERSION cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. > /dev/null
96
97 clang-tidy-$VERSION -checks='modernize-concat-nested-namespaces' ../foo.cpp -extra-arg=-std=c++17 -fix &> foo.log
98 if ! grep -q "namespace mozilla::dom" ../foo.cpp; then
99 echo "clang-tidy autofix didn't work"
100 cat foo.log
101 exit 1
102 fi
103 cd - &> /dev/null
104 rm -rf cmaketest
105
106 echo "Testing clangd-$VERSION ..."
107
108 echo '{
109 "jsonrpc": "2.0",
110 "id": 0,
111 "method": "initialize",
112 "params": {
113 "capabilities": {
114 "textDocument": {
115 "completion": {
116 "completionItem": {
117 "snippetSupport": true
118 }
119 }
120 }
121 },
122 "trace": "off"
123 }
124 }
125 ---
126 {
127 "jsonrpc": "2.0",
128 "method": "textDocument/didOpen",
129 "params": {
130 "textDocument": {
131 "uri": "test:///main.cpp",
132 "languageId": "cpp",
133 "version": 1,
134 "text": "int func_with_args(int a, int b);\nint main() {\nfunc_with\n}"
135 }
136 }
137 }
138 ---
139 {
140 "jsonrpc": "2.0",
141 "id": 1,
142 "method": "textDocument/completion",
143 "params": {
144 "textDocument": {
145 "uri": "test:///main.cpp"
146 },
147 "position": {
148 "line": 2,
149 "character": 7
150 }
151 }
152 }
153 ---
154 {
155 "jsonrpc": "2.0",
156 "id": 4,
157 "method": "shutdown"
158 }
159 ---
160 {
161 "jsonrpc": "2.0",
162 "method": "exit"
163 }
164 ' > a.json
165
166 clangd-$VERSION -lit-test -pch-storage=memory < a.json &> foo.log
167 if ! grep -q '"insertText": "func_with_args(${1:int a}, ${2:int b})",' foo.log; then
168 echo "clangd didn't export what we were expecting"
169 cat foo.log
170 exit 1
171 fi
172
173 echo 'namespace mozilla {
174 namespace dom {
175 void foo();
176
177 int fonction_avec_args(int a, float b);
178 int main() {
179 fonction_avec_args
180 }
181
182 }
183 }
184 ' > foo.cpp
185 content=$(sed ':a;N;$!ba;s/\n/\\n/g' foo.cpp)
186 echo '{
187 "jsonrpc": "2.0",
188 "id": 0,
189 "method": "initialize",
190 "params": {
191 "capabilities": {
192 "textDocument": {
193 "completion": {
194 "completionItem": {
195 "snippetSupport": true
196 }
197 }
198 }
199 },
200 "trace": "off"
201 }
202 }
203 ---
204 {
205 "jsonrpc": "2.0",
206 "method": "textDocument/didOpen",
207 "params": {
208 "textDocument": {
209 "uri": "file:///'$(pwd)'/cmaketest/foo.cpp",
210 "languageId": "cpp",
211 "version": 1,
212 "text": "'$content'"
213 }
214 }
215 }
216 ---
217 {
218 "jsonrpc": "2.0",
219 "id": 1,
220 "method": "textDocument/completion",
221 "params": {
222 "textDocument": {
223 "uri": "file:///'$(pwd)'/cmaketest/foo.cpp"
224 },
225 "position": {
226 "line": 6,
227 "character": 18
228 }
229 }
230 }
231 ---
232 {
233 "jsonrpc": "2.0",
234 "id": 4,
235 "method": "shutdown"
236 }
237 ---
238 {
239 "jsonrpc": "2.0",
240 "method": "exit"
241 }
242 ' > a.json
243
244 rm -rf cmaketest && mkdir cmaketest
245 cat > cmaketest/CMakeLists.txt <<EOF
246 cmake_minimum_required(VERSION 2.8.12)
247 project(SanityCheck)
248 add_library(MyLibrary foo.cpp)
249 EOF
250 mkdir cmaketest/standard
251 cp foo.cpp cmaketest/
252 cp a.json cmaketest/standard
253 cd cmaketest/standard
254
255 # run with cmake
256
257 CXX=clang-$VERSION cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. > /dev/null
258 # TODO this test is useless as it doesn't leverage foo.cpp or the compiledb
259 clangd-$VERSION -lit-test -pch-storage=memory < a.json &> foo.log
260 if ! grep -q '"insertText": "fonction_avec_args(${1:int a}, ${2:float b})",' foo.log; then
261 echo "clangd didn't export what we were expecting"
262 cat foo.log
263 exit 1
264 fi
265 cd - &> /dev/null
266 rm -rf cmaketest
267
268
269 echo "Testing clang-$VERSION ..."
270
271 rm -f foo.log
272 echo 'int main() {return 0;}' > foo.c
273 clang-$VERSION foo.c
274
275 echo '#include <stdio.h>
276 int main() {
277 printf("lli foo");
278 return 0;
279 }' > foo.c
280 clang-$VERSION -S -emit-llvm foo.c
281 llc-$VERSION foo.ll
282 if ! lli-$VERSION foo.ll|grep -q "lli foo"; then
283 echo "Not lli correct output"
284 lli-$VERSION foo.ll
285 exit 1
286 fi
287 opt-$VERSION -S -O3 foo.ll -o opt.ll
288 if ! lli-$VERSION opt.ll|grep -q "lli foo"; then
289 echo "Not lli correct output after opt"
290 lli-$VERSION opt.ll
291 exit 1
292 fi
293
294 clang-$VERSION -O3 -emit-llvm foo.c -c -o foo.bc
295 chmod +x foo.bc
296 # only run if the binfmt is installed correctly
297 /usr/sbin/update-binfmts --display llvm-$VERSION-runtime.binfmt &> foo.log || true
298 if grep -q "interpreter = /usr/bin/lli-" foo.log; then
299 /usr/sbin/update-binfmts --enable llvm-$VERSION-runtime.binfmt || true
300 if ! ./foo.bc|grep -q "lli foo"; then
301 echo "executing ./foo.bc failed"
302 ./foo.bc || true
303 #exit 1
304 fi
305
306 clang-$VERSION -O3 -emit-llvm foo.c -c -o foo.bc
307 chmod +x foo.bc
308 if ! ./foo.bc|grep -q "lli foo"; then
309 echo "executing ./foo.bc failed"
310 ./foo.bc || true
311 #exit 1
312 fi
313 fi # binfmt test
314
315 if ! llvm-dis-$VERSION < foo.bc|grep -q "lli foo"; then
316 echo "llvm assembly code failed"
317 llvm-dis-$VERSION < foo.bc
318 exit 1
319 fi
320
321 echo '#include <stddef.h>' > foo.c
322 clang-$VERSION -c foo.c
323
324 # https://bugs.launchpad.net/bugs/1810860
325 clang-$VERSION -dumpversion &> foo.log
326 if grep -q 4.2.1 foo.log; then
327 echo "dumpversion still returns 4.2.1"
328 echo "it should return the clang version"
329 cat foo.log
330 exit 1
331 fi
332
333 # bug 903709
334 echo '#include <stdatomic.h>
335 void increment(atomic_size_t *arg) {
336 atomic_fetch_add(arg, 1);
337 } ' > foo.c
338
339 clang-$VERSION -v -c foo.c &> /dev/null
340
341 echo "#include <fenv.h>" > foo.cc
342 NBLINES=$(clang++-$VERSION -P -E foo.cc|wc -l)
343 if test $NBLINES -lt 100; then
344 echo "Error: more than 100 lines should be returned"
345 exit 42
346 fi
347
348 if [ $DEB_HOST_ARCH != "arm64" -a $DEB_HOST_ARCH != "ppc64el" ]; then
349 # Fails on arm64 with
350 # /usr/lib/llvm-10/lib/clang/10.0.0/include/mmintrin.h:33:5: error: use of undeclared identifier '__builtin_ia32_emms'; did you mean '__builtin_isless'?
351 echo '#include <emmintrin.h>' > foo.cc
352 clang++-$VERSION -c foo.cc
353 fi
354
355 # Bug 913213
356 echo '#include <limits.h>' | clang-$VERSION -E - > /dev/null
357
358 # Bug launchpad #1488254
359 echo '
360 #include <string>
361 std::string hello = "Hello, world!\n";
362 ' > foo.cc
363
364 echo '
365 #include <string>
366 #include <iostream>
367 extern std::string hello;
368 int main() {
369 std::cout << hello;
370 return 0;
371 } ' > bar.cc
372
373 g++ -c foo.cc && g++ foo.o bar.cc && ./a.out > /dev/null || true
374 clang++-$VERSION -c foo.cc && clang++-$VERSION foo.o bar.cc && ./a.out > /dev/null
375 g++ -c foo.cc && clang++-$VERSION foo.o bar.cc && ./a.out > /dev/null || true
376 clang++-$VERSION -c foo.cc -fPIC && g++ foo.o bar.cc && ./a.out > /dev/null || true
377
378 ## test z3
379 echo '
380 void clang_analyzer_eval(int);
381 void testBitwiseRules(unsigned int a, int b) {
382 clang_analyzer_eval((1 & a) <= 1); // expected-warning{{TRUE}}
383 // with -analyzer-constraints=z3, it can tell that it is FALSE
384 // without the option, it is unknown
385 clang_analyzer_eval((b | -2) >= 0); // expected-warning{{FALSE}}
386 }
387 ' > foo.c
388 if dpkg -l|grep -q libz3-dev; then
389 # Should work
390 clang-$VERSION -cc1 -analyze -analyzer-constraints=range -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false -analyzer-constraints=z3 foo.c
391 else
392 echo "z3 support not available"
393 fi
394
395 # Should fail
396 clang-$VERSION -cc1 -analyze -analyzer-constraints=range -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false foo.c &> foo.log || true
397 if grep -q "File a.c Line 7: UNKNOWN" foo.log; then
398 echo "Should fail without -analyzer-constraints=z3"
399 exit 1
400 fi
401
402 if dpkg -l|grep -q libz3-dev; then
403 clang-$VERSION -cc1 -analyze -analyzer-constraints=range -analyzer-checker=core,debug.ExprInspection -analyzer-constraints=z3 foo.c &> foo.log
404 if ! grep -q "2 warnings generated." foo.log; then
405 echo "Should find 2 warnings"
406 exit 1
407 fi
408 else
409 echo "z3 support not available"
410 fi
411
412 clang-$VERSION -cc1 -analyze -analyzer-constraints=range -analyzer-checker=core,debug.ExprInspection foo.c &> foo.log
413 if ! grep -q "3 warnings generated." foo.log; then
414 echo "Should find 3 warnings"
415 exit 1
416 fi
417
418 # bug 827866
419 echo 'bool testAndSet(void *atomic) {
420 return __atomic_test_and_set(atomic, __ATOMIC_SEQ_CST);
421 }'> foo.cpp
422 clang++-$VERSION -c -target aarch64-linux-gnu foo.cpp
423 if ! file foo.o 2>&1 | grep -i -q "aarch64"; then
424 echo "Could not find the string 'aarch64' in the output of file. Output:"
425 file foo.o
426 exit 42
427 fi
428
429 clang-$VERSION --target=arm-linux-gnueabihf -dM -E -xc - < /dev/null &> foo.log
430 if ! grep -q "#define __ARM_ARCH 7" foo.log; then
431 # bug 930008
432 echo "The target arch for arm should be v7"
433 cat foo.log
434 exit 42
435 fi
436
437 echo '
438 #include <string.h>
439 int
440 main ()
441 {
442 (void) strcat;
443 return 0;
444 }' > foo.c
445 clang-$VERSION -c foo.c
446
447 echo '#include <errno.h>
448 int main() {} ' > foo.c
449 clang-$VERSION foo.c
450
451 echo '#include <chrono>
452 int main() { }' > foo.cpp
453 clang++-$VERSION -std=c++11 foo.cpp
454
455 echo "Testing linking clang-cpp ..."
456
457 clang-$VERSION -lclang-cpp$VERSION -v foo.cpp -o o &> /dev/null || true
458 if ! ldd o 2>&1|grep -q libclang-cpp; then
459 echo "Didn't link against libclang-cpp$VERSION"
460 exit 42
461 fi
462 ./o > /dev/null
463
464 # Check that the symlink is correct
465 ls -al /usr/lib/llvm-$VERSION/lib/libclang-cpp.so.$VERSION > /dev/null
466
467 echo "Testing code coverage ..."
468
469 echo '#include <stdio.h>
470 int main() {
471 if (1==1) {
472 printf("true");
473 }else{
474 printf("false");
475 return 42;
476 }
477 return 0;}' > foo.c
478 clang-$VERSION --coverage foo.c -o foo
479 ./foo > /dev/null
480 if test ! -f foo.gcno; then
481 echo "Coverage failed";
482 fi
483
484 echo "#include <iterator>" > foo.cpp
485 clang++-$VERSION -c foo.cpp
486
487 echo "Testing linking ..."
488 if test ! -f /usr/lib/llvm-$VERSION/bin/../lib/LLVMgold.so; then
489 echo "Install llvm-$VERSION-dev"
490 exit 1
491 fi
492
493 echo '#include <stdio.h>
494 int main() {
495 if (1==1) {
496 printf("true");
497 }else{
498 printf("false");
499 return 42;
500 }
501 return 0;}' > foo.c
502 rm foo bar.cc
503
504 clang-$VERSION -flto foo.c -o foo
505 ./foo > /dev/null
506
507 clang-$VERSION -fuse-ld=gold foo.c -o foo
508 ./foo > /dev/null
509
510 # test thinlto
511 echo "int foo(void) { return 0; }"> foo.c
512 echo "int foo(void); int main() {foo(); return 0;}">main.c
513 clang-$VERSION -flto=thin -O2 foo.c main.c -o foo
514 ./foo > /dev/null
515 clang-$VERSION -flto=thin -O2 foo.c main.c -c
516
517 echo "Testing lld-$VERSION ..."
518
519 if test ! -f /usr/bin/lld-$VERSION; then
520 echo "Install lld-$VERSION"
521 exit 1
522 fi
523 clang-$VERSION -fuse-ld=lld -O2 foo.c main.c -o foo
524 ./foo > /dev/null
525
526 if ls -al1 /usr/bin/ld.lld|grep ld.lld-$VERSION; then
527 # https://bugs.llvm.org/show_bug.cgi?id=40659
528 # -fuse-ld=lld will call lld
529 # Mismatch of version can fail the check
530 # so, only run it when /usr/bin/lld == $VERSION
531 clang-$VERSION -fuse-ld=lld -flto -O2 foo.c main.c -o foo
532 ./foo > /dev/null
533 fi
534
535 clang-$VERSION -fuse-ld=lld-$VERSION -O2 foo.c main.c -o foo
536 ./foo > /dev/null
537
538 # Bug 916975
539 file foo &> foo.log
540 if ! grep -q "BuildID" foo.log; then
541 echo "BuildID isn't part of the generated binary (lld generation)"
542 exit 1
543 fi
544 # Bug 916975
545 clang-$VERSION -O2 foo.c main.c -o foo2
546 file foo2 &> foo2.log
547 if ! grep -q "BuildID" foo2.log; then
548 echo "BuildID isn't part of the generated binary (ld generation)"
549 exit 1
550 fi
551
552 strip foo2
553 file foo2 &> foo2.log
554 if ! grep -q "BuildID" foo2.log; then
555 echo "BuildID isn't part of the generated binary (stripped)"
556 exit 1
557 fi
558 rm foo2 foo2.log
559
560 if test ! -f /usr/lib/llvm-$VERSION/bin/llvm-symbolizer; then
561 echo "Install llvm-$VERSION"
562 exit 1
563 fi
564
565 echo "vzeroupper" | llvm-exegesis-$VERSION -mode=uops -snippets-file=- &> foo.log || true
566 if grep -q -E "(built without libpfm|cannot initialize libpfm)" foo.log; then
567 echo "could not run llvm-exegesis correctly"
568 cat foo.log|head
569 exit 42
570 fi
571
572 if test ! -f /usr/lib/llvm-$VERSION/lib/libFuzzer.a; then
573 echo "Install libfuzzer-$VERSION-dev";
574 exit -1;
575 fi
576
577 echo "Testing libfuzzer-$VERSION-dev ..."
578
579 cat << EOF > test_fuzzer.cc
580 #include <stdint.h>
581 #include <stddef.h>
582 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
583 if (size > 0 && data[0] == 'H')
584 if (size > 1 && data[1] == 'I')
585 if (size > 2 && data[2] == '!')
586 __builtin_trap();
587 return 0;
588 }
589
590 EOF
591
592 clang++-$VERSION -fsanitize=address -fsanitize-coverage=edge,trace-pc test_fuzzer.cc /usr/lib/llvm-$VERSION/lib/libFuzzer.a
593 if ! ./a.out 2>&1 | grep -q -E "(Test unit written|PreferSmall)"; then
594 echo "fuzzer failed"
595 exit 42
596 fi
597
598 clang++-$VERSION -fsanitize=address,fuzzer test_fuzzer.cc
599 if ! ./a.out 2>&1 | grep -q "libFuzzer: deadly signal"; then
600 echo "fuzzer failed"
601 fi
602
603 echo 'int main(int argc, char **argv) {
604 int *array = new int[100];
605 delete [] array;
606 return array[argc]; // BOOM
607 }' > foo.cpp
608 clang++-$VERSION -O1 -g -fsanitize=address -fno-omit-frame-pointer foo.cpp
609 ASAN_OPTIONS=verbosity=1 ./a.out &> foo.log || true
610 if ! grep -q "Init done" foo.log; then
611 echo "asan verbose mode failed"
612 cat foo.log
613 exit 42
614 fi
615
616 # See also https://bugs.llvm.org/show_bug.cgi?id=39514 why
617 # /usr/bin/llvm-symbolizer-7 doesn't work
618 ASAN_OPTIONS=verbosity=2:external_symbolizer_path=/usr/lib/llvm-$VERSION/bin/llvm-symbolizer ./a.out &> foo.log || true
619 if ! grep -q "Using llvm-symbolizer" foo.log; then
620 echo "could not find llvm-symbolizer path"
621 cat foo.log
622 exit 42
623 fi
624 if ! grep -q "new\[\](unsigned" foo.log; then
625 echo "could not symbolize correctly"
626 cat foo.log
627 exit 42
628 fi
629
630 if ! grep -q "foo.cpp:3:3" foo.log; then
631 echo "could not symbolize correctly"
632 cat foo.log
633 exit 42
634 fi
635 ./a.out &> foo.log || true
636 if ! grep -q "new\[\](unsigned" foo.log; then
637 echo "could not symbolize correctly"
638 cat foo.log
639 exit 42
640 fi
641
642 if ! grep -q "foo.cpp:3:3" foo.log; then
643 echo "could not symbolize correctly"
644 cat foo.log
645 exit 42
646 fi
647
648 # Example from https://github.com/google/fuzzing/blob/master/tutorial/libFuzzerTutorial.md
649 # coverage fuzzing
650 cat << EOF > StandaloneFuzzTargetMain.c
651 #include <assert.h>
652 #include <stdio.h>
653 #include <stdlib.h>
654
655 extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
656 __attribute__((weak)) extern int LLVMFuzzerInitialize(int *argc, char ***argv);
657 int main(int argc, char **argv) {
658 fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
659 if (LLVMFuzzerInitialize)
660 LLVMFuzzerInitialize(&argc, &argv);
661 for (int i = 1; i < argc; i++) {
662 fprintf(stderr, "Running: %s\n", argv[i]);
663 FILE *f = fopen(argv[i], "r");
664 assert(f);
665 fseek(f, 0, SEEK_END);
666 size_t len = ftell(f);
667 fseek(f, 0, SEEK_SET);
668 unsigned char *buf = (unsigned char*)malloc(len);
669 size_t n_read = fread(buf, 1, len, f);
670 fclose(f);
671 assert(n_read == len);
672 LLVMFuzzerTestOneInput(buf, len);
673 free(buf);
674 fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
675 }
676 }
677 EOF
678
679 cat << EOF > fuzz_me.cc
680 #include <stdint.h>
681 #include <stddef.h>
682
683 bool FuzzMe(const uint8_t *Data, size_t DataSize) {
684 return DataSize >= 3 &&
685 Data[0] == 'F' &&
686 Data[1] == 'U' &&
687 Data[2] == 'Z' &&
688 Data[3] == 'Z';
689 }
690
691 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
692 FuzzMe(Data, Size);
693 return 0;
694 }
695 EOF
696 clang-$VERSION -fprofile-instr-generate -fcoverage-mapping fuzz_me.cc StandaloneFuzzTargetMain.c
697
698 rm -rf CORPUS
699 mkdir -p CORPUS
700 echo -n A > CORPUS/A
701 ./a.out CORPUS/* &> /dev/null
702 if ! ./a.out CORPUS/* 2>&1 | grep -q "running 1 inputs"; then
703 echo "Coverage fuzzing failed"
704 exit 1
705 fi
706 llvm-profdata-$VERSION merge -sparse *.profraw -o default.profdata
707 llvm-cov-$VERSION show a.out -instr-profile=default.profdata -name=FuzzMe &> foo.log
708 if ! grep -q "return DataSize >= 3" foo.log; then
709 echo "llvm-cov didn't show the expected output in fuzzing"
710 exit 1
711 fi
712 echo -n FUZA > CORPUS/FUZA && ./a.out CORPUS/* &> /dev/null
713 llvm-profdata-$VERSION merge -sparse *.profraw -o default.profdata
714 llvm-cov-$VERSION show a.out -instr-profile=default.profdata -name=FuzzMe &> foo.log
715 if ! grep -q "Data\[3\] == 'Z';" foo.log; then
716 echo "llvm-cov didn't show the expected output in fuzzing"
717 exit 1
718 fi
719 rm -rf CORPUS fuzz_me.cc StandaloneFuzzTargetMain.c
720
721 echo "Testing sanitizers ..."
722
723 echo '#include <stdlib.h>
724 int main() {
725 char *x = (char*)malloc(10 * sizeof(char*));
726 free(x);
727 return x[5];
728 }
729 ' > foo.c
730 clang-$VERSION -o foo -fsanitize=address -O1 -fno-omit-frame-pointer -g foo.c
731 if ! ./foo 2>&1 | grep -q heap-use-after-free ; then
732 echo "sanitize=address is failing"
733 exit 42
734 fi
735
736 # Bug #876973
737 echo '
738 #include <stdio.h>
739 int main(int argc, char **argv)
740 {
741 printf("Hello world!\n");
742 return 0;
743 }' > foo.c
744
745 # segfaults on 32bit with "-lc" library (also 6.0 does segfault)
746 clang-$VERSION -fsanitize=address foo.c -o foo -lc
747 ./foo &> /dev/null || true
748
749 echo '
750 #include <pthread.h>
751 #include <stdio.h>
752
753 int Global;
754
755 void *Thread1(void *x) {
756 Global++;
757 return NULL;
758 }
759
760 void *Thread2(void *x) {
761 Global--;
762 return NULL;
763 }
764
765 int main() {
766 pthread_t t[2];
767 pthread_create(&t[0], NULL, Thread1, NULL);
768 pthread_create(&t[1], NULL, Thread2, NULL);
769 pthread_join(t[0], NULL);
770 pthread_join(t[1], NULL);
771 } ' > foo.c
772
773 clang-$VERSION -o foo -fsanitize=thread -g -O1 foo.c
774 if ! strings ./foo 2>&1 | grep -q "tsan"; then
775 echo "binary doesn't contain tsan code"
776 strings foo
777 exit 42
778 fi
779 if ! ./foo 2>&1 | grep -q "data race"; then
780 echo "sanitize=address is failing"
781 exit 42
782 fi
783
784 echo '
785 class a {
786 public:
787 ~a();
788 };
789 template <typename, typename> using b = a;
790 struct f {
791 template <typename d> using e = b<a, d>;
792 };
793 struct g {
794 typedef f::e<int> c;
795 };
796 class h {
797 struct : g::c { int i; };
798 };
799 struct m {
800 h i;
801 };
802 template <typename> void __attribute__((noreturn)) j();
803 void k() {
804 m l;
805 j<int>();
806 }' > foo.cpp
807 clang++-$VERSION -std=c++14 -O3 -fsanitize=address -fsanitize=undefined -c foo.cpp -fno-crash-diagnostics
808
809
810 # fails on 32 bit, seems a real BUG in the package, using 64bit static libs?
811 LANG=C clang-$VERSION -fsanitize=fuzzer test_fuzzer.cc &> foo.log || true
812 if ! grep "No such file or directory" foo.log; then
813 # This isn't failing on 64, so, look at the results
814 if ! ./a.out 2>&1 | grep -q -E "(Test unit written|PreferSmall)"; then
815 echo "fuzzer. Output:"
816 ./a.out || true
817 if [ $DEB_HOST_ARCH != "arm64" -a $DEB_HOST_ARCH != "ppc64el" ]; then
818 # Don't fail on arm64 and ppc64el
819 exit 42
820 fi
821 fi
822 fi
823
824 echo 'int main() {
825 int a=0;
826 return a;
827 }
828 ' > foo.c
829 clang-$VERSION -g -o bar foo.c
830
831 # ABI issue between gcc & clang with clang 7
832 # https://bugs.llvm.org/show_bug.cgi?id=39427
833 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913271
834 if test $VERSION -eq 7; then
835 echo '
836 #include <llvm/ADT/ArrayRef.h>
837 #include <llvm/ADT/Optional.h>
838 namespace llvm { class Constant{}; class Type; class Value; }
839 extern llvm::Constant* bar (llvm::Type*, llvm::Constant*, llvm::ArrayRef<llvm::Value*>, bool, llvm::Optional<unsigned> o, llvm::Type*);
840 #ifdef PART2
841 llvm::Constant* bar (llvm::Type*, llvm::Constant*, llvm::ArrayRef<llvm::Value*>, bool, llvm::Optional<unsigned> o, llvm::Type*)
842 {
843 return o.hasValue()?static_cast<llvm::Constant*>(nullptr)+1:nullptr;
844 }
845 #endif
846 #ifndef PART2
847 static llvm::Constant* doConstantRef(llvm::Type* type, llvm::Constant* var, llvm::ArrayRef<llvm::Value*> steps)
848 {
849 llvm::Optional<unsigned> inRangeIndex;
850 return bar(type, var, steps, false, inRangeIndex, nullptr);
851 }
852 bool foo()
853 {
854 llvm::Constant* var = nullptr;
855 llvm::Value* zero = nullptr;
856 llvm::Value* indexes[2] = {zero, zero};
857 llvm::ArrayRef<llvm::Value*> steps(indexes, 2);
858 auto result = doConstantRef(nullptr, var, steps);
859 return result;
860 }
861 int main()
862 {
863 return foo();
864 }
865 #endif
866 ' > foo.cpp
867 FLAGS="-I/usr/lib/llvm-$VERSION/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -fno-strict-aliasing -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -ffunction-sections -fdata-sections -O2 -DNDEBUG -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
868
869 clang++-$VERSION -c -o part1.o foo.cpp $FLAGS
870 if test -f /usr/bin/g++; then
871 g++ -c -o part2.o -DPART2 foo.cpp $FLAGS
872 clang++-$VERSION -o foo part1.o part2.o $FLAGS
873 ./foo
874 fi
875 rm part1.o part2.o
876 fi
877
878 if test ! -f /usr/lib/llvm-$VERSION/lib/libomp.so; then
879 echo "Install libomp-$VERSION-dev";
880 exit -1;
881 fi
882
883 # OpenMP
884 cat <<EOF > foo.c
885 //test.c
886 #include "omp.h"
887 #include <stdio.h>
888
889 int main(void) {
890 #pragma omp parallel
891 printf("thread %d\n", omp_get_thread_num());
892 }
893 EOF
894 clang-$VERSION foo.c -fopenmp -o o
895 ./o > /dev/null
896
897 if test ! -f /usr/lib/llvm-$VERSION/include/c++/v1/vector; then
898 echo "Install libc++-$VERSION-dev";
899 exit -1;
900 fi
901
902 if test ! -f /usr/lib/llvm-$VERSION/lib/libc++abi.so; then
903 echo "Install libc++abi-$VERSION-dev";
904 exit -1;
905 fi
906
907
908 # libc++
909 echo '
910 #include <vector>
911 #include <string>
912 #include <iostream>
913 using namespace std;
914 int main(void) {
915 vector<string> tab;
916 tab.push_back("the");
917 tab.push_back("world");
918 tab.insert(tab.begin(), "Hello");
919
920 for(vector<string>::iterator it=tab.begin(); it!=tab.end(); ++it)
921 {
922 cout << *it << " ";
923 }
924 return 0;
925 }' > foo.cpp
926 clang++-$VERSION -stdlib=libc++ foo.cpp -o o
927 if ! ldd o 2>&1|grep -q libc++.so.1; then
928 echo "not linked against libc++.so.1"
929 exit -1
930 fi
931 if ! ldd o 2>&1|grep -q libc++abi.so.1; then
932 echo "not linked against libc++abi.so.1"
933 exit -1
934 fi
935
936 ./o > /dev/null
937 clang++-$VERSION -std=c++11 -stdlib=libc++ foo.cpp -o o
938 ./o > /dev/null
939
940 # Bug 889832
941 echo '#include <iostream>
942 int main() {}' | clang++-$VERSION -std=c++1z -x c++ -stdlib=libc++ -
943
944 if test ! -f /usr/lib/llvm-$VERSION/include/cxxabi.h; then
945 echo "Install libc++abi-$VERSION-dev";
946 exit -1;
947 fi
948
949 # Force the usage of libc++abi
950 clang++-$VERSION -stdlib=libc++ -lc++abi foo.cpp -o o
951 ./o > /dev/null
952 if ! ldd o 2>&1|grep -q libc++abi.so.1; then
953 echo "not linked against libc++abi.so.1"
954 exit -1
955 fi
956
957 # Use the libc++abi and uses the libstc++ headers
958 clang++-$VERSION -lc++abi foo.cpp -o o
959 ./o > /dev/null
960 if ! ldd o 2>&1|grep -q libstdc++.so.; then
961 echo "not linked against libstdc++"
962 exit -1
963 fi
964
965 # fs from C++17
966 echo '
967 #include <filesystem>
968 #include <type_traits>
969 using namespace std::filesystem;
970 int main() {
971 static_assert(std::is_same<
972 path,
973 std::filesystem::path
974 >::value, "");
975 }' > foo.cpp
976 clang++-$VERSION -std=c++17 -stdlib=libc++ foo.cpp -o o
977 ./o > /dev/null
978
979 # Bug LP#1586215
980 echo '
981 #include <string>
982 #include <iostream>
983
984 int main()
985 {
986 try
987 {
988 std::string x;
989 char z = x.at(2);
990 std::cout << z << std::endl;
991 }
992 catch (...)
993 {
994 }
995
996 return 0;
997 }' > foo.cpp
998 clang++-$VERSION -stdlib=libc++ -Wall -Werror foo.cpp -o foo
999 ./foo
1000
1001 # Bug https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914201
1002 echo '
1003 #include <math.h>
1004 int main(void)
1005 {
1006 double f = 2.0;
1007 if (isnan(f))
1008 return 1;
1009 return 0;
1010 }' > foo.c
1011 clang-$VERSION -Wconversion -Werror foo.c &> /dev/null || true
1012
1013 if test -f /usr/bin/g++; then
1014 g++ -nostdinc++ -I/usr/lib/llvm-$VERSION/bin/../include/c++/v1/ -L/usr/lib/llvm-$VERSION/lib/ \
1015 foo.cpp -nodefaultlibs -std=c++17 -lc++ -lc++abi -lm -lc -lgcc_s -lgcc|| true
1016 ./o > /dev/null
1017 fi
1018
1019
1020 if test ! -f /usr/lib/llvm-$VERSION/include/polly/LinkAllPasses.h; then
1021 echo "Install libclang-common-$VERSION-dev for polly";
1022 exit -1;
1023 fi
1024
1025 echo "Testing polly (libclang-common-$VERSION-dev) ..."
1026
1027 # Polly
1028 echo "
1029 #define N 1536
1030 float A[N][N];
1031 float B[N][N];
1032 float C[N][N];
1033
1034 void init_array()
1035 {
1036 int i, j;
1037 for (i = 0; i < N; i++) {
1038 for (j = 0; j < N; j++) {
1039 A[i][j] = (1+(i*j)%1024)/2.0;
1040 B[i][j] = (1+(i*j)%1024)/2.0;
1041 }
1042 }
1043 }
1044
1045 int main()
1046 {
1047 int i, j, k;
1048 double t_start, t_end;
1049 init_array();
1050 for (i = 0; i < N; i++) {
1051 for (j = 0; j < N; j++) {
1052 C[i][j] = 0;
1053 for (k = 0; k < N; k++)
1054 C[i][j] = C[i][j] + A[i][k] * B[k][j];
1055 }
1056 }
1057 return 0;
1058 }
1059 " > foo.c
1060 clang-$VERSION -O3 -mllvm -polly -mllvm -polly-parallel -lgomp foo.c
1061 # Comment because of https://bugs.llvm.org/show_bug.cgi?id=43164
1062 #clang-$VERSION -O3 -mllvm -polly -mllvm -lgomp -polly-parallel foo.c
1063 clang-$VERSION -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine foo.c
1064 clang-$VERSION -S -fsave-optimization-record -emit-llvm foo.c -o matmul.s
1065 opt-$VERSION -S -polly-canonicalize matmul.s > matmul.preopt.ll > /dev/null
1066 opt-$VERSION -basicaa -polly-ast -analyze -q matmul.preopt.ll -polly-process-unprofitable > /dev/null
1067 if test ! -f /usr/lib/llvm-$VERSION/share/opt-viewer/opt-viewer.py; then
1068 echo "Install llvm-$VERSION-tools"
1069 exit 42
1070 fi
1071 /usr/lib/llvm-$VERSION/share/opt-viewer/opt-viewer.py -source-dir . matmul.opt.yaml -o ./output > /dev/null
1072
1073 if ! grep -q "not inlined into" output/foo.c.html 2>&1; then
1074 echo "Could not find the output from polly"
1075 exit -1
1076 fi
1077
1078 echo "
1079 int foo(int x, int y) __attribute__((always_inline));
1080 int foo(int x, int y) { return x + y; }
1081 int bar(int j) { return foo(j, j - 2); }" > foo.cc
1082 clang-$VERSION -O2 -Rpass=inline foo.cc -c &> foo.log
1083 if ! grep -q "cost=always" foo.log; then
1084 echo "-Rpass fails"
1085 cat foo.log
1086 exit 1
1087 fi
1088 echo "
1089 int X = 0;
1090
1091 int main() {
1092 int i;
1093 for (i = 0; i < 100; i++)
1094 X += i;
1095 return 0;
1096 }"> foo.cc
1097 clang++-$VERSION -O2 -fprofile-instr-generate foo.cc -o foo
1098 LLVM_PROFILE_FILE="foo-%p.profraw" ./foo
1099 llvm-profdata-$VERSION merge -output=foo.profdata foo-*.profraw
1100 clang++-$VERSION -O2 -fprofile-instr-use=foo.profdata foo.cc -o foo
1101
1102 # https://bugs.llvm.org/show_bug.cgi?id=44870
1103 cat <<EOF > foo.cpp
1104 #include <clang/CodeGen/BackendUtil.h>
1105
1106 using namespace clang;
1107
1108 int main() {
1109 DiagnosticsEngine* diags;
1110 HeaderSearchOptions* hsOpts;
1111 CodeGenOptions* cgOpts;
1112 TargetOptions* tOpts;
1113 LangOptions* lOpts;
1114 llvm::DataLayout* tDesc;
1115 llvm::Module* m;
1116 BackendAction* action;
1117 std::unique_ptr<raw_pwrite_stream> AsmOutStream;
1118
1119 EmitBackendOutput(*diags, *hsOpts, *cgOpts, *tOpts, *lOpts, *tDesc, m, *action, std::move(AsmOutStream));
1120 }
1121 EOF
1122 clang++-$VERSION foo.cpp -o test -lclangBasic -lclangCodeGen -lclangDriver -lclangFrontend -lclangFrontendTool -lclangCodeGen -lclangRewriteFrontend -lclangARCMigrate -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangCrossTU -lclangIndex -lclangFrontend -lclangDriver -lclangParse -lclangSerialization -lclangSema -lclangAnalysis -lclangEdit -lclangFormat -lclangToolingInclusions -lclangToolingCore -lclangRewrite -lclangASTMatchers -lclangAST -lclangLex -lclangBasic -ldl /usr/lib/llvm-$VERSION/lib/libLLVM-$VERSION.so -lclangCodeGen -lclangDriver -lclangFrontend -lclangFrontendTool -lclangRewriteFrontend -lclangARCMigrate -lclangStaticAnalyzerFrontend -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangCrossTU -lclangIndex -lclangParse -lclangSerialization -lclangSema -lclangAnalysis -lclangEdit -lclangFormat -lclangToolingInclusions -lclangToolingCore -lclangRewrite -lclangASTMatchers -lclangAST -lclangLex -ldl -I /usr/lib/llvm-$VERSION/include/ -L/usr/lib/llvm-$VERSION/lib/ -lPolly -lPollyPPCG -lPollyISL
1123
1124
1125 if test ! -f /usr/bin/lldb-$VERSION; then
1126 echo "Install lldb-$VERSION";
1127 exit -1;
1128 fi
1129
1130 echo "b main
1131 run
1132 bt
1133 quit" > lldb-cmd.txt
1134
1135 echo "Testing lldb-$VERSION ..."
1136 # bug 913946
1137 lldb-$VERSION -s lldb-cmd.txt bar &> foo.log
1138
1139 if dpkg -l|grep -q clang-$VERSION-dbgsym; then
1140 # Testing if clang dbg symbol are here
1141 lldb-$VERSION -s lldb-cmd.txt clang-$VERSION &> foo.log
1142 if ! grep "main at driver.cpp" foo.log; then
1143 echo "Could not find the debug info"
1144 echo "Or the main() of clang isn't in driver.cpp anymore"
1145 exit -1
1146 fi
1147 else
1148 echo "clang-$VERSION-dbgsym isn't installed"
1149 fi
1150
1151 echo '
1152 #include <vector>
1153 int main (void)
1154 { std::vector<int> a;
1155 a.push_back (0);
1156 }
1157 ' > foo.cpp
1158 clang++-$VERSION -g -o foo foo.cpp
1159 echo 'target create "./foo"
1160 b main
1161 r
1162 n
1163 p a
1164 quit' > lldb-cmd.txt
1165 lldb-$VERSION -s lldb-cmd.txt ./foo &> foo.log
1166 if ! grep -q "stop reason = step over" foo.log; then
1167 echo "Could not find the lldb expected output"
1168 cat foo.log
1169 # do not fail on i386, never worked here
1170 if [ $DEB_HOST_ARCH != "i386" ]; then
1171 exit 42
1172 fi
1173 fi
1174
1175 if test ! -f /usr/lib/llvm-$VERSION/lib/libclangToolingInclusions.a; then
1176 echo "Install libclang-$VERSION-dev";
1177 exit -1;
1178 fi
1179
1180 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=943623
1181 rm *.o
1182 /usr/bin/ar x /usr/lib/llvm-$VERSION/lib/libclangIndex.a &> /dev/null
1183 file *.o a> foo.log
1184 rm *.o
1185 if grep "LLVM IR bitcode" foo.log; then
1186 echo "found LLVM IR bitcode in the libclangIndex.a file"
1187 echo "Should be elf"
1188 exit -2
1189 fi
1190
1191 echo "Testing cmake build ..."
1192
1193 if grep -q lit-cpuid /usr/lib/llvm-$VERSION/lib/cmake/llvm/LLVMExports*.cmake; then
1194 echo "LLVMExports*.cmake should not have lit-cpuid"
1195 echo "it introduces a dependency between llvm-9 => lldb"
1196 exit -1
1197 fi
1198
1199 rm -rf cmaketest && mkdir cmaketest
1200 cat > cmaketest/CMakeLists.txt <<EOF
1201 cmake_minimum_required(VERSION 2.8.12)
1202 project(SanityCheck)
1203 find_package(LLVM $VERSION REQUIRED CONFIG)
1204 message(STATUS "LLVM_CMAKE_DIR: \${LLVM_CMAKE_DIR}")
1205 if(NOT EXISTS "\${LLVM_TOOLS_BINARY_DIR}/clang")
1206 message(FATAL_ERROR "Invalid LLVM_TOOLS_BINARY_DIR: \${LLVM_TOOLS_BINARY_DIR}")
1207 endif()
1208 # TODO add version to ClangConfig.cmake and use $VERSION below
1209 find_package(Clang REQUIRED CONFIG)
1210 find_file(H clang/AST/ASTConsumer.h PATHS \${CLANG_INCLUDE_DIRS} NO_DEFAULT_PATH)
1211 message(STATUS "CLANG_INCLUDE_DIRS: \${CLANG_INCLUDE_DIRS}")
1212 if(NOT H)
1213 message(FATAL_ERROR "Invalid Clang header path: \${CLANG_INCLUDE_DIRS}")
1214 endif()
1215 EOF
1216 mkdir cmaketest/standard cmaketest/explicit
1217 # "Test: CMake find LLVM and Clang in default path"
1218 (cd cmaketest/standard && CC=clang-$VERSION CXX=clang++-$VERSION cmake .. > /dev/null)
1219 # "Test: CMake find LLVM and Clang in explicit prefix path"
1220 (cd cmaketest/explicit && CC=clang-$VERSION CXX=clang++-$VERSION CMAKE_PREFIX_PATH=/usr/lib/llvm-$VERSION cmake .. > /dev/null)
1221 rm -rf cmaketest
1222
1223 # Test case for bug #900440
1224 rm -rf cmaketest && mkdir cmaketest
1225 cat > cmaketest/CMakeLists.txt <<EOF
1226 cmake_minimum_required(VERSION 2.8.12)
1227 project(testllvm)
1228
1229 find_package(LLVM CONFIG REQUIRED)
1230 find_package(Clang CONFIG REQUIRED)
1231
1232 if(NOT LLVM_VERSION STREQUAL Clang_VERSION)
1233 #message(FATAL_ERROR "LLVM ${LLVM_VERSION} not matching to Clang ${Clang_VERSION}")
1234 endif()
1235 EOF
1236 mkdir cmaketest/foo/
1237 (cd cmaketest/foo && cmake .. > /dev/null)
1238 rm -rf cmaketest
1239
1240
1241
1242
1243 CLANG=clang-$VERSION
1244 #command -v "$CLANG" 1>/dev/null 2>/dev/null || { printf "Usage:\n%s CLANGEXE [ARGS]\n" "$0" 1>&2; exit 1; }
1245 #shift
1246
1247 TEMPDIR=$(mktemp -d); trap "rm -rf \"$TEMPDIR\"" 0
1248
1249 echo "Testing all other sanitizers ..."
1250
1251 echo "int main() { return 1; }" > foo.c
1252 # fails to run on i386 with the following error:
1253 #clang: error: unsupported option '-fsanitize=efficiency-working-set' for target 'i686-pc-linux-gnu'
1254 clang-$VERSION -fsanitize=efficiency-working-set -o foo foo.c || true
1255 ./foo &> /dev/null || true
1256
1257 cat > "$TEMPDIR/test.c" <<EOF
1258 #include <stdlib.h>
1259 #include <stdio.h>
1260 int main ()
1261 {
1262 #if __has_feature(address_sanitizer)
1263 puts("address_sanitizer");
1264 #endif
1265 #if __has_feature(thread_sanitizer)
1266 puts("thread_sanitizer");
1267 #endif
1268 #if __has_feature(memory_sanitizer)
1269 puts("memory_sanitizer");
1270 #endif
1271 #if __has_feature(undefined_sanitizer)
1272 puts("undefined_sanitizer");
1273 #endif
1274 #if __has_feature(dataflow_sanitizer)
1275 puts("dataflow_sanitizer");
1276 #endif
1277 #if __has_feature(efficiency_sanitizer)
1278 puts("efficiency_sanitizer");
1279 #endif
1280 printf("Ok\n");
1281 return EXIT_SUCCESS;
1282 }
1283 EOF
1284
1285 F=$(clang-$VERSION --target=x86_64-unknown-linux-gnu --rtlib=compiler-rt --print-libgcc-file-name)
1286 if test ! $F; then
1287 echo "Cannot find $F"
1288 echo "TODO check if the exit1 can be put back"
1289 # exit 1
1290 else
1291 echo "$F is one of the compiler-rt file"
1292 fi
1293
1294 # only for AMD64 for now
1295 # many sanitizers only work on AMD64
1296 # x32 programs need to be enabled in the kernel bootparams for debian
1297 # (https://wiki.debian.org/X32Port)
1298 #
1299 # SYSTEM should iterate multiple targets (eg. x86_64-unknown-none-gnu for embedded)
1300 # MARCH should iterate the library architectures via flags
1301 # LIB should iterate the different libraries
1302 echo "if it fails, please run"
1303 echo "apt-get install libc6-dev:i386 libgcc-5-dev:i386 libc6-dev-x32 libx32gcc-5-dev libx32gcc-9-dev"
1304 for SYSTEM in ""; do
1305 for MARCH in -m64 -m32 -mx32 "-m32 -march=i686"; do
1306 for LIB in --rtlib=compiler-rt -fsanitize=address -fsanitize=thread -fsanitize=memory -fsanitize=undefined -fsanitize=dataflow; do # -fsanitize=efficiency-working-set; do
1307 if test "$MARCH" == "-m32" -o "$MARCH" == "-mx32"; then
1308 if test $LIB == "-fsanitize=thread" -o $LIB == "-fsanitize=memory" -o $LIB == "-fsanitize=dataflow" -o $LIB == "-fsanitize=address" -o $LIB == "-fsanitize=undefined"; then
1309 echo "Skip $MARCH / $LIB";
1310 continue
1311 fi
1312 fi
1313 if test "$MARCH" == "-m32 -march=i686"; then
1314 if test $LIB == "-fsanitize=memory" -o $LIB == "-fsanitize=thread" -o $LIB == "-fsanitize=dataflow"; then
1315 echo "Skip $MARCH / $LIB";
1316 continue
1317 fi
1318 fi
1319 XARGS="$SYSTEM $MARCH $LIB"
1320 printf "\nTest: clang %s\n" "$XARGS"
1321 rm -f "$TEMPDIR/test"
1322 "$CLANG" $XARGS -o "$TEMPDIR/test" "$@" "$TEMPDIR/test.c" || true
1323 [ ! -e "$TEMPDIR/test" ] || { "$TEMPDIR/test" || printf 'Error\n'; }
1324 done
1325 done
1326 done
1327
1328 echo "If the following fails, try setting an environment variable such as:"
1329 echo "OBJC_INCLUDE_PATH=/usr/lib/gcc/x86_64-linux-gnu/8/include"
1330 echo "libobjc-9-dev should be also installed"
1331 echo "#include <objc/objc.h>" > foo.m
1332 #clang-$VERSION -c foo.m
1333
1334 if test ! -f /usr/lib/llvm-$VERSION/lib/libclangBasic.a; then
1335 echo "Install libclang-$VERSION-dev"
1336 exit 1
1337 fi
1338
1339 #clean up
1340 rm -f a.out bar crash-* foo foo.* lldb-cmd.txt main.* test_fuzzer.cc foo.* o
1341 rm -rf output matmul.* *profraw opt.ll
1342
1343 echo "Completed"