static-analysis.sh 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #!/usr/bin/env bash
  2. function do_cppcheck()
  3. {
  4. local SOURCES=$(find $(git rev-parse --show-toplevel) | grep -E "\.(cpp|cc|c|h)\$")
  5. local CPPCHECK=$(which cppcheck)
  6. if [ $? -ne 0 ]; then
  7. echo "[!] cppcheck not installed. Failed to run static analysis the source code." >&2
  8. exit 1
  9. fi
  10. ## Suppression list ##
  11. # This list will explain the detail of suppressed warnings.
  12. # The prototype of the item should be like:
  13. # "- [{file}] {spec}: {reason}"
  14. #
  15. # - [hello-1.c] unusedFunction: False positive of init_module and cleanup_module.
  16. # - [*.c] missingIncludeSystem: Focus on the example code, not the kernel headers.
  17. local OPTS="
  18. --enable=warning,performance,information
  19. --suppress=unusedFunction:hello-1.c
  20. --suppress=missingIncludeSystem
  21. --std=c89 "
  22. $CPPCHECK $OPTS --xml ${SOURCES} 2> cppcheck.xml
  23. local ERROR_COUNT=$(cat cppcheck.xml | grep -E -c "</error>" )
  24. if [ $ERROR_COUNT -gt 0 ]; then
  25. echo "Cppcheck failed: $ERROR_COUNT error(s)"
  26. cat cppcheck.xml
  27. exit 1
  28. fi
  29. }
  30. function do_sparse()
  31. {
  32. git clone git://git.kernel.org/pub/scm/devel/sparse/sparse.git --depth=1
  33. if [ $? -ne 0 ]; then
  34. echo "Failed to download sparse."
  35. exit 1
  36. fi
  37. pushd sparse
  38. make sparse || exit 1
  39. sudo make INST_PROGRAMS=sparse PREFIX=/usr install || exit 1
  40. popd
  41. local SPARSE=$(which sparse)
  42. make -C examples C=2 CHECK="$SPARSE" 2> sparse.log
  43. local WARNING_COUNT=$(cat sparse.log | grep -E -c " warning:" )
  44. local ERROR_COUNT=$(cat sparse.log | grep -E -c " error:" )
  45. local COUNT=`expr $WARNING_COUNT + $ERROR_COUNT`
  46. if [ $COUNT -gt 0 ]; then
  47. echo "Sparse failed: $WARNING_COUNT warning(s), $ERROR_COUNT error(s)"
  48. cat sparse.log
  49. exit 1
  50. fi
  51. make -C examples clean
  52. }
  53. function do_gcc()
  54. {
  55. local GCC=$(which gcc)
  56. if [ $? -ne 0 ]; then
  57. echo "[!] gcc is not installed. Failed to run static analysis with GCC." >&2
  58. exit 1
  59. fi
  60. make -C examples CONFIG_STATUS_CHECK_GCC=y STATUS_CHECK_GCC=$GCC 2> gcc.log
  61. local WARNING_COUNT=$(cat gcc.log | grep -E -c " warning:" )
  62. local ERROR_COUNT=$(cat gcc.log | grep -E -c " error:" )
  63. local COUNT=`expr $WARNING_COUNT + $ERROR_COUNT`
  64. if [ $COUNT -gt 0 ]; then
  65. echo "gcc failed: $WARNING_COUNT warning(s), $ERROR_COUNT error(s)"
  66. cat gcc.log
  67. exit 1
  68. fi
  69. make -C examples CONFIG_STATUS_CHECK_GCC=y STATUS_CHECK_GCC=$GCC clean
  70. }
  71. function do_smatch()
  72. {
  73. git clone https://github.com/error27/smatch.git --depth=1
  74. if [ $? -ne 0 ]; then
  75. echo "Failed to download smatch."
  76. exit 1
  77. fi
  78. pushd smatch
  79. make smatch || exit 1
  80. local SMATCH=$(pwd)/smatch
  81. popd
  82. make -C examples C=2 CHECK="$SMATCH -p=kernel" > smatch.log
  83. local WARNING_COUNT=$(cat smatch.log | egrep -c " warn:" )
  84. local ERROR_COUNT=$(cat smatch.log | egrep -c " error:" )
  85. local COUNT=`expr $WARNING_COUNT + $ERROR_COUNT`
  86. if [ $COUNT -gt 0 ]; then
  87. echo "Smatch failed: $WARNING_COUNT warning(s), $ERROR_COUNT error(s)"
  88. cat smatch.log | grep "warn:\|error:"
  89. exit 1
  90. fi
  91. make -C examples clean
  92. }
  93. do_cppcheck
  94. do_sparse
  95. do_gcc
  96. do_smatch
  97. exit 0