static-analysis.sh 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #!/usr/bin/env bash
  2. function do_cppcheck()
  3. {
  4. local SOURCES=$(find $(git rev-parse --show-toplevel) | egrep "\.(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,style,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 | egrep -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. wget -q http://www.kernel.org/pub/software/devel/sparse/dist/sparse-latest.tar.gz
  33. if [ $? -ne 0 ]; then
  34. echo "Failed to download sparse."
  35. exit 1
  36. fi
  37. tar -xzf sparse-latest.tar.gz
  38. pushd sparse-*/
  39. make sparse || exit 1
  40. sudo make INST_PROGRAMS=sparse PREFIX=/usr install || exit 1
  41. popd
  42. local SPARSE=$(which sparse)
  43. make -C examples C=2 CHECK="$SPARSE" 2> sparse.log
  44. local WARNING_COUNT=$(cat sparse.log | egrep -c " warning:" )
  45. local ERROR_COUNT=$(cat sparse.log | egrep -c " error:" )
  46. local COUNT=`expr $WARNING_COUNT + $ERROR_COUNT`
  47. if [ $COUNT -gt 0 ]; then
  48. echo "Sparse failed: $WARNING_COUNT warning(s), $ERROR_COUNT error(s)"
  49. cat sparse.log
  50. exit 1
  51. fi
  52. make -C examples clean
  53. }
  54. function do_gcc()
  55. {
  56. local GCC=$(which gcc-11)
  57. if [ $? -ne 0 ]; then
  58. echo "[!] gcc-11 is not installed. Failed to run static analysis with GCC." >&2
  59. exit 1
  60. fi
  61. make -C examples CONFIG_STATUS_CHECK_GCC=y STATUS_CHECK_GCC=$GCC 2> gcc.log
  62. local WARNING_COUNT=$(cat gcc.log | egrep -c " warning:" )
  63. local ERROR_COUNT=$(cat gcc.log | egrep -c " error:" )
  64. local COUNT=`expr $WARNING_COUNT + $ERROR_COUNT`
  65. if [ $COUNT -gt 0 ]; then
  66. echo "gcc failed: $WARNING_COUNT warning(s), $ERROR_COUNT error(s)"
  67. cat gcc.log
  68. exit 1
  69. fi
  70. make -C examples CONFIG_STATUS_CHECK_GCC=y STATUS_CHECK_GCC=$GCC clean
  71. }
  72. function do_smatch()
  73. {
  74. git clone https://github.com/error27/smatch.git --depth=1
  75. if [ $? -ne 0 ]; then
  76. echo "Failed to download smatch."
  77. exit 1
  78. fi
  79. pushd smatch
  80. make smatch || exit 1
  81. local SMATCH=$(pwd)/smatch
  82. popd
  83. make -C examples C=2 CHECK="$SMATCH -p=kernel" > smatch.log
  84. local WARNING_COUNT=$(cat smatch.log | egrep -c " warn:" )
  85. local ERROR_COUNT=$(cat smatch.log | egrep -c " error:" )
  86. local COUNT=`expr $WARNING_COUNT + $ERROR_COUNT`
  87. if [ $COUNT -gt 0 ]; then
  88. echo "Smatch failed: $WARNING_COUNT warning(s), $ERROR_COUNT error(s)"
  89. cat smatch.log | grep "warn:\|error:"
  90. exit 1
  91. fi
  92. make -C examples clean
  93. }
  94. do_cppcheck
  95. do_sparse
  96. do_gcc
  97. do_smatch
  98. exit 0