#!/bin/bash # Stop at the first error set -e if ! test -d debian/; then echo "$0: Could not find the debian/ directory" exit 1 fi VERSION=$(dpkg-parsechangelog | sed -rne "s,^Version: 1:([0-9]+).*,\1,p") DETAILED_VERSION=$(dpkg-parsechangelog | sed -rne "s,^Version: 1:([0-9.]+)(~|-)(.*),\1\2\3,p") DEB_HOST_ARCH=$(dpkg-architecture -qDEB_HOST_ARCH) LIST="libomp5-${VERSION}_${DETAILED_VERSION}_amd64.deb libomp-${VERSION}-dev_${DETAILED_VERSION}_amd64.deb lldb-${VERSION}_${DETAILED_VERSION}_amd64.deb python-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" echo "To install everything:" echo "sudo dpkg -i $LIST" L="" for f in $LIST; do L="$L $(echo $f|cut -d_ -f1)" done echo "or" echo "apt-get install $L" if test ! -f /usr/bin/llvm-config-$VERSION; then echo "Install llvm-$VERSION & llvm-$VERSION-dev" exit 1 fi if test ! -f /usr/lib/llvm-$VERSION/lib/libLLVM-$VERSION.so; then echo "Install llvm-$VERSION-dev" exit 1 fi echo "Testing llvm-$VERSION and llvm-$VERSION-dev ..." llvm-config-$VERSION --link-shared --libs &> /dev/null if llvm-config-$VERSION --cxxflags | grep " \-W"; then echo "llvm-config should not export -W warnings" exit 1 fi # Test https://bugs.llvm.org/show_bug.cgi?id=40059 nm /usr/lib/llvm-$VERSION/lib/libLLVMBitWriter.a &> foo.log if grep "File format not recognized" foo.log; then echo "nm libLLVMBitWriter.a contains 'File format not recognized'" exit 1 fi if test ! -f /usr/bin/scan-build-$VERSION; then echo "Install clang-tools-$VERSION" exit 1 fi echo "Testing clang-tools-$VERSION ..." echo ' void test() { int x; x = 1; // warn } '> foo.c # Ignore if gcc isn't available scan-build-$VERSION -o scan-build gcc -c foo.c &> /dev/null || true scan-build-$VERSION -o scan-build clang-$VERSION -c foo.c &> /dev/null scan-build-$VERSION --exclude non-existing/ --exclude /tmp/ -v clang-$VERSION -c foo.c &> /dev/null scan-build-$VERSION --exclude $(pwd) -v clang-$VERSION -c foo.c &> foo.log if ! grep -q -E "scan-build: 0 bugs found." foo.log; then echo "scan-build --exclude didn't ignore the defect" exit 42 fi rm -rf scan-build echo "Testing clang-$VERSION ..." rm -f foo.log echo 'int main() {return 0;}' > foo.c clang-$VERSION foo.c echo '#include ' > foo.c clang-$VERSION -c foo.c # https://bugs.launchpad.net/bugs/1810860 clang-$VERSION -dumpversion &> foo.log if grep -q 4.2.1 foo.log; then echo "dumpversion still returns 4.2.1" echo "Will be fixed with clang 9" # exit 1 fi # bug 903709 echo '#include void increment(atomic_size_t *arg) { atomic_fetch_add(arg, 1); } ' > foo.c clang-$VERSION -v -c foo.c &> /dev/null echo "#include " > foo.cc NBLINES=$(clang++-$VERSION -P -E foo.cc|wc -l) if test $NBLINES -lt 100; then echo "Error: more than 100 lines should be returned" exit 42 fi echo '#include ' > foo.cc clang++-$VERSION -c foo.cc # Bug 913213 echo '#include ' | clang-$VERSION -E - > /dev/null # Bug launchpad #1488254 echo ' #include std::string hello = "Hello, world!\n"; ' > foo.cc echo ' #include #include extern std::string hello; int main() { std::cout << hello; return 0; } ' > bar.cc g++ -c foo.cc && g++ foo.o bar.cc && ./a.out > /dev/null || true clang++-$VERSION -c foo.cc && clang++-$VERSION foo.o bar.cc && ./a.out > /dev/null g++ -c foo.cc && clang++-$VERSION foo.o bar.cc && ./a.out > /dev/null || true clang++-$VERSION -c foo.cc -fPIC && g++ foo.o bar.cc && ./a.out > /dev/null || true # bug 827866 echo 'bool testAndSet(void *atomic) { return __atomic_test_and_set(atomic, __ATOMIC_SEQ_CST); }'> foo.cpp clang++-$VERSION -c -target aarch64-linux-gnu foo.cpp if ! file foo.o 2>&1 | grep -i -q "aarch64"; then echo "Could not find the string 'aarch64' in the output of file. Output:" file foo.o exit 42 fi clang-$VERSION --target=arm-linux-gnueabihf -dM -E -xc - < /dev/null &> foo.log if ! grep -q "#define __ARM_ARCH 7" foo.log; then # bug 930008 echo "The target arch for arm should be v7" cat foo.log exit 42 fi echo ' #include int main () { (void) strcat; return 0; }' > foo.c clang-$VERSION -c foo.c echo '#include int main() {} ' > foo.c clang-$VERSION foo.c echo '#include int main() { }' > foo.cpp clang++-$VERSION -std=c++11 foo.cpp echo "Testing code coverage ..." echo '#include int main() { if (1==1) { printf("true"); }else{ printf("false"); return 42; } return 0;}' > foo.c clang-$VERSION --coverage foo.c -o foo ./foo > /dev/null if test ! -f foo.gcno; then echo "Coverage failed"; fi echo "#include " > foo.cpp clang++-$VERSION -c foo.cpp echo "Testing linking ..." if test ! -f /usr/lib/llvm-$VERSION/bin/../lib/LLVMgold.so; then echo "Install llvm-$VERSION-dev" exit 1 fi echo '#include int main() { if (1==1) { printf("true"); }else{ printf("false"); return 42; } return 0;}' > foo.c rm foo bar.cc clang-$VERSION -flto foo.c -o foo ./foo > /dev/null clang-$VERSION -fuse-ld=gold foo.c -o foo ./foo > /dev/null # test thinlto echo "int foo(void) { return 0; }"> foo.c echo "int foo(void); int main() {foo(); return 0;}">main.c clang-$VERSION -flto=thin -O2 foo.c main.c -o foo ./foo > /dev/null clang-$VERSION -flto=thin -O2 foo.c main.c -c echo "Testing lld-$VERSION ..." if test ! -f /usr/bin/lld-$VERSION; then echo "Install lld-$VERSION" exit 1 fi clang-$VERSION -fuse-ld=lld -O2 foo.c main.c -o foo ./foo > /dev/null if ls -al1 /usr/bin/ld.lld|grep ld.lld-$VERSION; then # https://bugs.llvm.org/show_bug.cgi?id=40659 # -fuse-ld=lld will call lld # Mismatch of version can fail the check # so, only run it when /usr/bin/lld == $VERSION clang-$VERSION -fuse-ld=lld -flto -O2 foo.c main.c -o foo ./foo > /dev/null fi clang-$VERSION -fuse-ld=lld-$VERSION -O2 foo.c main.c -o foo ./foo > /dev/null # Bug 916975 file foo &> foo.log if ! grep -q "BuildID" foo.log; then echo "BuildID isn't part of the generated binary (lld generation)" exit 1 fi # Bug 916975 clang-$VERSION -O2 foo.c main.c -o foo2 file foo2 &> foo2.log if ! grep -q "BuildID" foo2.log; then echo "BuildID isn't part of the generated binary (ld generation)" exit 1 fi strip foo2 file foo2 &> foo2.log if ! grep -q "BuildID" foo2.log; then echo "BuildID isn't part of the generated binary (stripped)" exit 1 fi rm foo2 foo2.log if test ! -f /usr/lib/llvm-$VERSION/bin/llvm-symbolizer; then echo "Install llvm-$VERSION" exit 1 fi echo "vzeroupper" | llvm-exegesis-$VERSION -mode=uops -snippets-file=- &> foo.log || true if grep -q -E "(built without libpfm|cannot initialize libpfm)" foo.log; then echo "could not run llvm-exegesis correctly" cat foo.log|head exit 42 fi if test ! -f /usr/lib/llvm-$VERSION/lib/libFuzzer.a; then echo "Install libfuzzer-$VERSION-dev"; exit -1; fi echo "Testing libfuzzer-$VERSION-dev ..." cat << EOF > test_fuzzer.cc #include #include extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size > 0 && data[0] == 'H') if (size > 1 && data[1] == 'I') if (size > 2 && data[2] == '!') __builtin_trap(); return 0; } EOF clang++-$VERSION -fsanitize=address -fsanitize-coverage=edge,trace-pc test_fuzzer.cc /usr/lib/llvm-$VERSION/lib/libFuzzer.a if ! ./a.out 2>&1 | grep -q -E "(Test unit written|PreferSmall)"; then echo "fuzzer" exit 42 fi echo 'int main(int argc, char **argv) { int *array = new int[100]; delete [] array; return array[argc]; // BOOM }' > foo.cpp clang++-$VERSION -O1 -g -fsanitize=address -fno-omit-frame-pointer foo.cpp ASAN_OPTIONS=verbosity=1 ./a.out &> foo.log || true if ! grep -q "Init done" foo.log; then echo "asan verbose mode failed" cat foo.log exit 42 fi # See also https://bugs.llvm.org/show_bug.cgi?id=39514 why # /usr/bin/llvm-symbolizer-7 doesn't work ASAN_OPTIONS=verbosity=2:external_symbolizer_path=/usr/lib/llvm-$VERSION/bin/llvm-symbolizer ./a.out &> foo.log || true if ! grep -q "Using llvm-symbolizer" foo.log; then echo "could not find llvm-symbolizer path" cat foo.log exit 42 fi if ! grep -q "new\[\](unsigned" foo.log; then echo "could not symbolize correctly" cat foo.log exit 42 fi if ! grep -q "foo.cpp:3:3" foo.log; then echo "could not symbolize correctly" cat foo.log exit 42 fi ./a.out &> foo.log || true if ! grep -q "new\[\](unsigned" foo.log; then echo "could not symbolize correctly" cat foo.log exit 42 fi if ! grep -q "foo.cpp:3:3" foo.log; then echo "could not symbolize correctly" cat foo.log exit 42 fi echo "Testing sanitizers ..." echo '#include int main() { char *x = (char*)malloc(10 * sizeof(char*)); free(x); return x[5]; } ' > foo.c clang-$VERSION -o foo -fsanitize=address -O1 -fno-omit-frame-pointer -g foo.c if ! ./foo 2>&1 | grep -q heap-use-after-free ; then echo "sanitize=address is failing" exit 42 fi # Bug #876973 echo ' #include int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }' > foo.c # segfaults on 32bit with "-lc" library (also 6.0 does segfault) clang-$VERSION -fsanitize=address foo.c -o foo -lc ./foo &> /dev/null || true echo ' class a { public: ~a(); }; template using b = a; struct f { template using e = b; }; struct g { typedef f::e c; }; class h { struct : g::c {}; }; struct m { h i; }; template void __attribute__((noreturn)) j(); void k() { m l; j(); }' > foo.cpp clang++-$VERSION -std=c++14 -O3 -fsanitize=address -fsanitize=undefined -c foo.cpp -fno-crash-diagnostics # fails on 32 bit, seems a real BUG in the package, using 64bit static libs? LANG=C clang-$VERSION -fsanitize=fuzzer test_fuzzer.cc &> foo.log || true if ! grep "No such file or directory" foo.log; then # This isn't failing on 64, so, look at the results if ! ./a.out 2>&1 | grep -q -E "(Test unit written|PreferSmall)"; then echo "fuzzer" exit 42 fi fi echo 'int main() { int a=0; return a; } ' > foo.c clang-$VERSION -g -o bar foo.c # ABI issue between gcc & clang with clang 7 # https://bugs.llvm.org/show_bug.cgi?id=39427 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=913271 if test $VERSION -eq 7; then echo ' #include #include namespace llvm { class Constant{}; class Type; class Value; } extern llvm::Constant* bar (llvm::Type*, llvm::Constant*, llvm::ArrayRef, bool, llvm::Optional o, llvm::Type*); #ifdef PART2 llvm::Constant* bar (llvm::Type*, llvm::Constant*, llvm::ArrayRef, bool, llvm::Optional o, llvm::Type*) { return o.hasValue()?static_cast(nullptr)+1:nullptr; } #endif #ifndef PART2 static llvm::Constant* doConstantRef(llvm::Type* type, llvm::Constant* var, llvm::ArrayRef steps) { llvm::Optional inRangeIndex; return bar(type, var, steps, false, inRangeIndex, nullptr); } bool foo() { llvm::Constant* var = nullptr; llvm::Value* zero = nullptr; llvm::Value* indexes[2] = {zero, zero}; llvm::ArrayRef steps(indexes, 2); auto result = doConstantRef(nullptr, var, steps); return result; } int main() { return foo(); } #endif ' > foo.cpp 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" clang++-$VERSION -c -o part1.o foo.cpp $FLAGS if test -f /usr/bin/g++; then g++ -c -o part2.o -DPART2 foo.cpp $FLAGS clang++-$VERSION -o foo part1.o part2.o $FLAGS ./foo fi rm part1.o part2.o fi if test ! -f /usr/lib/llvm-$VERSION/lib/libomp.so; then echo "Install libomp-$VERSION-dev"; exit -1; fi # OpenMP cat < foo.c //test.c #include "omp.h" #include int main(void) { #pragma omp parallel printf("thread %d\n", omp_get_thread_num()); } EOF clang-$VERSION foo.c -fopenmp -o o ./o > /dev/null if test ! -f /usr/lib/llvm-$VERSION/include/c++/v1/vector; then echo "Install libc++-$VERSION-dev"; exit -1; fi if test ! -f /usr/lib/llvm-$VERSION/lib/libc++abi.so; then echo "Install libc++abi-$VERSION-dev"; exit -1; fi # libc++ echo ' #include #include #include using namespace std; int main(void) { vector tab; tab.push_back("the"); tab.push_back("world"); tab.insert(tab.begin(), "Hello"); for(vector::iterator it=tab.begin(); it!=tab.end(); ++it) { cout << *it << " "; } return 0; }' > foo.cpp clang++-$VERSION -stdlib=libc++ foo.cpp -o o if ! ldd o 2>&1|grep -q libc++.so.1; then echo "not linked against libc++.so.1" exit -1 fi if ! ldd o 2>&1|grep -q libc++abi.so.1; then echo "not linked against libc++abi.so.1" exit -1 fi ./o > /dev/null clang++-$VERSION -std=c++11 -stdlib=libc++ foo.cpp -o o ./o > /dev/null clang++-$VERSION -std=c++14 -stdlib=libc++ foo.cpp -lc++experimental -o o ./o > /dev/null # Bug 889832 echo '#include int main() {}' | clang++-$VERSION -std=c++1z -x c++ -stdlib=libc++ - if test ! -f /usr/lib/llvm-$VERSION/include/cxxabi.h; then echo "Install libc++abi-$VERSION-dev"; exit -1; fi # Force the usage of libc++abi clang++-$VERSION -stdlib=libc++ -lc++abi foo.cpp -o o ./o > /dev/null if ! ldd o 2>&1|grep -q libc++abi.so.1; then echo "not linked against libc++abi.so.1" exit -1 fi # Use the libc++abi and uses the libstc++ headers clang++-$VERSION -lc++abi foo.cpp -o o ./o > /dev/null if ! ldd o 2>&1|grep -q libstdc++.so.; then echo "not linked against libstdc++" exit -1 fi # fs from C++17 echo ' #include #include using namespace std::filesystem; int main() { static_assert(std::is_same< path, std::filesystem::path >::value, ""); }' > foo.cpp clang++-$VERSION -std=c++17 -stdlib=libc++ foo.cpp -lc++experimental -lc++fs -o o ./o > /dev/null # Bug LP#1586215 echo ' #include #include int main() { try { std::string x; char z = x.at(2); std::cout << z << std::endl; } catch (...) { } return 0; }' > foo.cpp clang++-$VERSION -stdlib=libc++ -Wall -Werror foo.cpp -o foo ./foo # Bug https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914201 echo ' #include int main(void) { double f = 2.0; if (isnan(f)) return 1; return 0; }' > foo.c clang-$VERSION -Wconversion -Werror foo.c &> /dev/null || true if test -f /usr/bin/g++; then g++ -nostdinc++ -I/usr/lib/llvm-$VERSION/bin/../include/c++/v1/ -L/usr/lib/llvm-$VERSION/lib/ \ foo.cpp -nodefaultlibs -std=c++17 -lc++ -lc++abi -lm -lc -lgcc_s -lgcc|| true ./o > /dev/null fi if test ! -f /usr/lib/llvm-$VERSION/include/polly/LinkAllPasses.h; then echo "Install libclang-common-$VERSION-dev for polly"; exit -1; fi echo "Testing polly (libclang-common-$VERSION-dev) ..." # Polly echo " #define N 1536 float A[N][N]; float B[N][N]; float C[N][N]; void init_array() { int i, j; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { A[i][j] = (1+(i*j)%1024)/2.0; B[i][j] = (1+(i*j)%1024)/2.0; } } } int main() { int i, j, k; double t_start, t_end; init_array(); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { C[i][j] = 0; for (k = 0; k < N; k++) C[i][j] = C[i][j] + A[i][k] * B[k][j]; } } return 0; } " > foo.c clang-$VERSION -O3 -mllvm -polly foo.c clang-$VERSION -O3 -mllvm -polly -mllvm -polly-parallel -lgomp foo.c clang-$VERSION -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine foo.c clang-$VERSION -S -fsave-optimization-record -emit-llvm foo.c -o matmul.s opt-$VERSION -S -polly-canonicalize matmul.s > matmul.preopt.ll > /dev/null opt-$VERSION -basicaa -polly-ast -analyze -q matmul.preopt.ll -polly-process-unprofitable > /dev/null if test ! -f /usr/lib/llvm-$VERSION/share/opt-viewer/opt-viewer.py; then echo "Install llvm-$VERSION-tools" exit 42 fi /usr/lib/llvm-$VERSION/share/opt-viewer/opt-viewer.py -source-dir . matmul.opt.yaml -o ./output > /dev/null if ! grep -q "not inlined into" output/foo.c.html 2>&1; then echo "Could not find the output from polly" exit -1 fi echo " int foo(int x, int y) __attribute__((always_inline)); int foo(int x, int y) { return x + y; } int bar(int j) { return foo(j, j - 2); }" > foo.cc clang-$VERSION -O2 -Rpass=inline foo.cc -c &> foo.log if ! grep -q "cost=always" foo.log; then echo "-Rpass fails" cat foo.log exit 1 fi echo " int X = 0; int main() { int i; for (i = 0; i < 100; i++) X += i; return 0; }"> foo.cc clang++-$VERSION -O2 -fprofile-instr-generate foo.cc -o foo LLVM_PROFILE_FILE="foo-%p.profraw" ./foo llvm-profdata-$VERSION merge -output=foo.profdata foo-*.profraw clang++-$VERSION -O2 -fprofile-instr-use=foo.profdata foo.cc -o foo if test ! -f /usr/bin/lldb-$VERSION; then echo "Install lldb-$VERSION"; exit -1; fi echo "b main run bt quit" > lldb-cmd.txt echo "Testing lldb-$VERSION ..." # bug 913946 lldb-$VERSION -s lldb-cmd.txt bar &> foo.log if dpkg -l|grep -q clang-$VERSION-dbgsym; then # Testing if clang dbg symbol are here lldb-$VERSION -s lldb-cmd.txt clang-$VERSION &> foo.log if ! grep "main at driver.cpp" foo.log; then echo "Could not find the debug info" echo "Or the main() of clang isn't in driver.cpp anymore" exit -1 fi else echo "clang-$VERSION-dbgsym isn't installed" fi echo ' #include int main (void) { std::vector a; a.push_back (0); } ' > foo.cpp clang++-$VERSION -g -o foo foo.cpp echo 'target create "./foo" b main r n p a quit' > lldb-cmd.txt lldb-$VERSION -s lldb-cmd.txt ./foo &> foo.log if ! grep -q "stop reason = step over" foo.log; then echo "Could not find the lldb expected output" cat foo.log # do not fail on i386, never worked here if [ $DEB_HOST_ARCH != "i386" ]; then exit 42 fi fi if test ! -f /usr/lib/llvm-$VERSION/lib/libclangToolingInclusions.a; then echo "Install libclang-$VERSION-dev"; exit -1; fi echo "Testing cmake build ..." rm -rf cmaketest && mkdir cmaketest cat > cmaketest/CMakeLists.txt < /dev/null) # "Test: CMake find LLVM and Clang in explicit prefix path" (cd cmaketest/explicit && CC=clang-$VERSION CXX=clang++-$VERSION CMAKE_PREFIX_PATH=/usr/lib/llvm-$VERSION cmake .. > /dev/null) rm -rf cmaketest # Test case for bug #900440 rm -rf cmaketest && mkdir cmaketest cat > cmaketest/CMakeLists.txt < /dev/null) rm -rf cmaketest CLANG=clang-$VERSION #command -v "$CLANG" 1>/dev/null 2>/dev/null || { printf "Usage:\n%s CLANGEXE [ARGS]\n" "$0" 1>&2; exit 1; } #shift TEMPDIR=$(mktemp -d); trap "rm -rf \"$TEMPDIR\"" 0 echo "Testing all other sanitizers ..." echo "int main() { return 1; }" > foo.c # fails to run on i386 with the following error: #clang: error: unsupported option '-fsanitize=efficiency-working-set' for target 'i686-pc-linux-gnu' clang-$VERSION -fsanitize=efficiency-working-set -o foo foo.c || true ./foo &> /dev/null || true cat > "$TEMPDIR/test.c" < #include int main () { #if __has_feature(address_sanitizer) puts("address_sanitizer"); #endif #if __has_feature(thread_sanitizer) puts("thread_sanitizer"); #endif #if __has_feature(memory_sanitizer) puts("memory_sanitizer"); #endif #if __has_feature(undefined_sanitizer) puts("undefined_sanitizer"); #endif #if __has_feature(dataflow_sanitizer) puts("dataflow_sanitizer"); #endif #if __has_feature(efficiency_sanitizer) puts("efficiency_sanitizer"); #endif printf("Ok\n"); return EXIT_SUCCESS; } EOF F=$(clang-$VERSION --target=x86_64-unknown-linux-gnu --rtlib=compiler-rt --print-libgcc-file-name) if test ! $F; then echo "Cannot find $F" echo "TODO check if the exit1 can be put back" # exit 1 else echo "$F is one of the compiler-rt file" fi # only for AMD64 for now # many sanitizers only work on AMD64 # x32 programs need to be enabled in the kernel bootparams for debian # (https://wiki.debian.org/X32Port) # # SYSTEM should iterate multiple targets (eg. x86_64-unknown-none-gnu for embedded) # MARCH should iterate the library architectures via flags # LIB should iterate the different libraries echo "if it fails, please run" echo "apt-get install libc6-dev:i386 libgcc-5-dev:i386 libc6-dev-x32 libx32gcc-5-dev libx32gcc-8-dev" for SYSTEM in ""; do for MARCH in -m64 -m32 -mx32 "-m32 -march=i686"; do for LIB in --rtlib=compiler-rt -fsanitize=address -fsanitize=thread -fsanitize=memory -fsanitize=undefined -fsanitize=dataflow; do # -fsanitize=efficiency-working-set; do if test "$MARCH" == "-m32" -o "$MARCH" == "-mx32"; then if test $LIB == "-fsanitize=thread" -o $LIB == "-fsanitize=memory" -o $LIB == "-fsanitize=dataflow" -o $LIB == "-fsanitize=address" -o $LIB == "-fsanitize=undefined"; then echo "Skip $MARCH / $LIB"; continue fi fi if test "$MARCH" == "-m32 -march=i686"; then if test $LIB == "-fsanitize=memory" -o $LIB == "-fsanitize=thread" -o $LIB == "-fsanitize=dataflow"; then echo "Skip $MARCH / $LIB"; continue fi fi XARGS="$SYSTEM $MARCH $LIB" printf "\nTest: clang %s\n" "$XARGS" rm -f "$TEMPDIR/test" "$CLANG" $XARGS -o "$TEMPDIR/test" "$@" "$TEMPDIR/test.c" || true [ ! -e "$TEMPDIR/test" ] || { "$TEMPDIR/test" || printf 'Error\n'; } done done done echo "If the following fails, try setting an environment variable such as:" echo "OBJC_INCLUDE_PATH=/usr/lib/gcc/x86_64-linux-gnu/8/include" echo "libobjc-8-dev should be also installed" echo "#include " > foo.m #clang-$VERSION -c foo.m if test ! -f /usr/lib/llvm-$VERSION/lib/libclangBasic.a; then echo "Install libclang-$VERSION-dev" exit 1 fi #clean up rm -f a.out bar crash-* foo foo.* lldb-cmd.txt main.* test_fuzzer.cc foo.* o rm -rf output matmul.* *profraw echo "Completed"