diff options
Diffstat (limited to 'debian/qualify-clang.sh')
-rwxr-xr-x | debian/qualify-clang.sh | 885 |
1 files changed, 885 insertions, 0 deletions
diff --git a/debian/qualify-clang.sh b/debian/qualify-clang.sh new file mode 100755 index 0000000..f50f86c --- /dev/null +++ b/debian/qualify-clang.sh @@ -0,0 +1,885 @@ +#!/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 <stddef.h>' > 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 <stdatomic.h> +void increment(atomic_size_t *arg) { + atomic_fetch_add(arg, 1); +} ' > foo.c + +clang-$VERSION -v -c foo.c &> /dev/null + +echo "#include <fenv.h>" > 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 <emmintrin.h>' > foo.cc +clang++-$VERSION -c foo.cc + +# Bug 913213 +echo '#include <limits.h>' | clang-$VERSION -E - > /dev/null + +# Bug launchpad #1488254 +echo ' +#include <string> +std::string hello = "Hello, world!\n"; +' > foo.cc + +echo ' +#include <string> +#include <iostream> +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 <string.h> +int +main () +{ + (void) strcat; + return 0; +}' > foo.c +clang-$VERSION -c foo.c + +echo '#include <errno.h> +int main() {} ' > foo.c +clang-$VERSION foo.c + +echo '#include <chrono> +int main() { }' > foo.cpp +clang++-$VERSION -std=c++11 foo.cpp + +echo "Testing code coverage ..." + +echo '#include <stdio.h> +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 <iterator>" > 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 <stdio.h> +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 <stdint.h> +#include <stddef.h> +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 <stdlib.h> +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 <stdio.h> +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 <typename, typename> using b = a; +struct f { + template <typename d> using e = b<a, d>; +}; +struct g { + typedef f::e<int> c; +}; +class h { + struct : g::c {}; +}; +struct m { + h i; +}; +template <typename> void __attribute__((noreturn)) j(); +void k() { + m l; + j<int>(); +}' > 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 <llvm/ADT/ArrayRef.h> +#include <llvm/ADT/Optional.h> +namespace llvm { class Constant{}; class Type; class Value; } +extern llvm::Constant* bar (llvm::Type*, llvm::Constant*, llvm::ArrayRef<llvm::Value*>, bool, llvm::Optional<unsigned> o, llvm::Type*); +#ifdef PART2 +llvm::Constant* bar (llvm::Type*, llvm::Constant*, llvm::ArrayRef<llvm::Value*>, bool, llvm::Optional<unsigned> o, llvm::Type*) +{ + return o.hasValue()?static_cast<llvm::Constant*>(nullptr)+1:nullptr; +} +#endif +#ifndef PART2 +static llvm::Constant* doConstantRef(llvm::Type* type, llvm::Constant* var, llvm::ArrayRef<llvm::Value*> steps) +{ + llvm::Optional<unsigned> 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<llvm::Value*> 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 <<EOF > foo.c +//test.c +#include "omp.h" +#include <stdio.h> + +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 <vector> +#include <string> +#include <iostream> +using namespace std; +int main(void) { + vector<string> tab; + tab.push_back("the"); + tab.push_back("world"); + tab.insert(tab.begin(), "Hello"); + + for(vector<string>::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 <iostream> +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 <filesystem> +#include <type_traits> +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 <string> +#include <iostream> + +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 <math.h> +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 <vector> +int main (void) +{ std::vector<int> 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 <<EOF +cmake_minimum_required(VERSION 2.8.12) +project(SanityCheck) +find_package(LLVM $VERSION REQUIRED CONFIG) +message(STATUS "LLVM_CMAKE_DIR: \${LLVM_CMAKE_DIR}") +if(NOT EXISTS "\${LLVM_TOOLS_BINARY_DIR}/clang") +message(FATAL_ERROR "Invalid LLVM_TOOLS_BINARY_DIR: \${LLVM_TOOLS_BINARY_DIR}") +endif() +# TODO add version to ClangConfig.cmake and use $VERSION below +find_package(Clang REQUIRED CONFIG) +find_file(H clang/AST/ASTConsumer.h PATHS \${CLANG_INCLUDE_DIRS} NO_DEFAULT_PATH) +message(STATUS "CLANG_INCLUDE_DIRS: \${CLANG_INCLUDE_DIRS}") +if(NOT H) +message(FATAL_ERROR "Invalid Clang header path: \${CLANG_INCLUDE_DIRS}") +endif() +EOF +mkdir cmaketest/standard cmaketest/explicit +# "Test: CMake find LLVM and Clang in default path" +(cd cmaketest/standard && CC=clang-$VERSION CXX=clang++-$VERSION cmake .. > /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 <<EOF +cmake_minimum_required(VERSION 2.8.12) +project(testllvm) + +find_package(LLVM CONFIG REQUIRED) +find_package(Clang CONFIG REQUIRED) + +if(NOT LLVM_VERSION STREQUAL Clang_VERSION) + #message(FATAL_ERROR "LLVM ${LLVM_VERSION} not matching to Clang ${Clang_VERSION}") +endif() +EOF +mkdir cmaketest/foo/ +(cd cmaketest/foo && cmake .. > /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" <<EOF +#include <stdlib.h> +#include <stdio.h> +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 <objc/objc.h>" > 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" |