Skip to content

Commit

Permalink
Add simple static checker using clang-query
Browse files Browse the repository at this point in the history
  • Loading branch information
real-or-random committed Oct 16, 2020
1 parent c6b6b8f commit 0858d47
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ libtool
*~
*.log
*.trs
compile_commands.commands.json
compile_commands.json
src/libsecp256k1-config.h
src/libsecp256k1-config.h.in
src/ecmult_static_context.h
Expand Down
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ osx_image: xcode10.1
addons:
apt:
packages:
- clang-tools-10
- libgmp-dev
- valgrind
- libtool-bin
- bear
compiler:
- clang
- gcc
Expand Down Expand Up @@ -43,27 +45,32 @@ matrix:
addons:
apt:
packages:
- clang-tools-10
- gcc-multilib
- libgmp-dev:i386
- valgrind
- libtool-bin
- bear
- libc6-dbg:i386
- compiler: clang
env: HOST=i686-linux-gnu
os: linux
addons:
apt:
packages:
- clang-tools-10
- gcc-multilib
- valgrind
- libtool-bin
- bear
- libc6-dbg:i386
- compiler: gcc
env: HOST=i686-linux-gnu
os: linux
addons:
apt:
packages:
- clang-tools-10
- gcc-multilib
- valgrind
- libtool-bin
Expand All @@ -74,6 +81,7 @@ matrix:
addons:
apt:
packages:
- clang-tools-10
- gcc-multilib
- libgmp-dev:i386
- valgrind
Expand Down Expand Up @@ -104,5 +112,7 @@ after_script:
- cat ./exhaustive_tests.log
- cat ./valgrind_ctime_test.log
- cat ./bench.log
- cat ./clang-query.log
- cat ./compile_commands.json
- $CC --version
- valgrind --version
53 changes: 53 additions & 0 deletions clang-query.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/sh

set -u

matcher=$(cat <<'EOF'
set print-matcher true
enable output detailed-ast
### Expressions of any floating point type (unless in a system header)
match expr(allOf(unless(isExpansionInSystemHeader()), hasType(realFloatingPointType())))
### Calls to memcmp (secp256k1_memcmp_var should be used instead)
match callExpr(callee(functionDecl(hasName("memcmp"))))
### Reserved identifiers (unless in a system header) with external linkage or at file scope.
# Any function is in file scope. Any variable with static storage (unless static local variable) is in file scope.
# Allowed exceptions: __builtin_expect
# We need the "::" due to LLVM bug 47879.
match namedDecl(allOf(unless(isExpansionInSystemHeader()), anyOf(hasExternalFormalLinkage(), functionDecl(), varDecl(allOf(hasStaticStorageDuration(), unless(isStaticLocal())))), allOf(matchesName("^::(_|((mem|is|to|str|wcs)[a-z]))"), unless(hasAnyName("__builtin_expect")))))
### Reserved type names (unless in a system header)
# Allowed exceptions: uint128_t, int128_t, __int128_t, __uint128_t (the latter two are "implicit", i.e., added by the compiler)
match typedefDecl(allOf(unless(isExpansionInSystemHeader()), matchesName("(^::u?int)|(_t$)"), unless(hasAnyName("int128_t", "uint128_t", "__int128_t", "__uint128_t"))))
quit
EOF
)

# Poor man's JSON parser.
# This is not great but it works with the output of all common tools and it does not need extra dependencies.
files=$(grep 'file' compile_commands.json | uniq | cut -d '"' -f 4)
echo "Running clang-query on files:"
echo "$files"

output=$(echo "$matcher" | ${CLANG_QUERY:-clang-query} "$@" $files)
status=$?
if [ $status -ne 0 ]
then
exit $status
fi

echo "$output"
# For some reason, clang-query returns a zero status even if clang failed to process the file (LLVM Bug 47880).
# This is not a big issue. If clang errors, we'll notice that when trying to compile with clang anyway.
# We still try to catch this case by grepping also for "error:".
echo "$output" | grep -qE "^Match #|error:"
if [ $? -eq 0 ]
then
exit 1
fi

echo
exit 0
16 changes: 16 additions & 0 deletions contrib/travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ fi

if [ -n "$BUILD" ]
then
if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$TRAVIS_COMPILER" = "clang" ]
then
# Use bear to generate compile_commands.json
# This needs to be the first make command because otherwise make does not invoke the compiler because the files are up to date.
# We need to update this to "bear -- make" when we move to bear 3.0.
bear make -j2
fi
make -j2 "$BUILD"
fi
if [ "$RUN_VALGRIND" = "yes" ]
Expand Down Expand Up @@ -66,3 +73,12 @@ if [ "$CTIMETEST" = "yes" ]
then
./libtool --mode=execute valgrind --error-exitcode=42 ./valgrind_ctime_test > valgrind_ctime_test.log 2>&1
fi

# This would also run on gcc builds but there's no need to run it for both compilers.
if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$TRAVIS_COMPILER" = "clang" ]
then
# Abuse `script` to run make clang-query believe it's running with a terminal (see https://superuser.com/a/1434381/404598).
# This lets us write color codes to clang-query.log.
# (Passing `--extra-arg=-fcolor-diagnostics` to clang-query works only if stdout but not stderr is redirected to a file...)
CLANG_QUERY=clang-query-10 script -efqc "./clang-query.sh 2>&1" clang-query.log
fi

0 comments on commit 0858d47

Please sign in to comment.