Changes between Version 46 and Version 47 of BestPracticeHandbook


Ignore:
Timestamp:
Jun 18, 2015, 3:01:39 AM (7 years ago)
Author:
Niall Douglas
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • BestPracticeHandbook

    v46 v47  
    278278Enabling Microsoft's static analyser is easy, simply add /analyze to the compiler command line. Your compile will take ten times longer and new warnings will appear. Note though that the MSVC static analyser is quite prone to false positives like miscounting array entries consumed. You can suppress those using the standard #pragma warning(disable: XXX) system around the offending code.
    279279
    280 Enabling clang's static analyser is slightly harder. You'll need to replace the normal call of the compiler with whatever tool is set into the CXX environment variable by the scan-build tool. See http://clang-analyzer.llvm.org/scan-build.html. For Boost projects, I found this script to work well:
     280clang comes with two static analysis tools, the static analyser (no false positives) and the lint tool (many false positives), and you should enable both. The clang lint tool is easy, simply call `clang-tidy` albeit with somewhat weird arguments. Enabling clang's static analyser is slightly harder. You'll need to replace the normal call of the compiler with whatever tool is set into the CXX environment variable by the scan-build tool. See http://clang-analyzer.llvm.org/scan-build.html. For Boost projects, I found this script to work well:
    281281
    282282{{{
     
    286286git submodule update --init --recursive
    287287cd boost-local
    288 /usr/share/clang/scan-build-3.4/scan-build --use-analyzer=/usr/bin/clang-3.4 -o "$REPORTS" ./b2 toolset=gcc-4.7 libs/afio/test -a --test=test_all.cpp --link-test
     288cd libs/afio/test
     289./test_file_glob.sh
     290cd ../../..
     291rm -rf clang-tidy-warnings.txt
     292clang-tidy-3.7 -checks='*,-google-*,-misc-macro-parentheses,-readability-braces-around-statements,-readability-named-parameter,-llvm-namespace-comment' -header-filter='boost/afio/[^/]*.hpp' libs/afio/test/test_all.cpp -- -DNDEBUG -std=c++11 -I. -Ilibs/afio/test > clang-tidy-warnings.txt
     293clang-tidy-3.7 -checks='*,-google-*,-misc-macro-parentheses,-readability-braces-around-statements,-readability-named-parameter,-llvm-namespace-comment' -header-filter='boost/afio/detail/.*.hpp' libs/afio/test/test_all.cpp -- -DNDEBUG -std=c++11 -I. -Ilibs/afio/test >> clang-tidy-warnings.txt
     294cat clang-tidy-warnings.txt
     295if [ -s clang-tidy-warnings.txt ]; then exit 1; fi
     296/usr/share/clang/scan-build-3.7/scan-build --use-analyzer=/usr/bin/clang-3.7 -o "$REPORTS" ./b2 toolset=gcc-4.8 libs/afio/test -a --test=test_all.cpp --link-test
    289297}}}
    290298
     
    296304}}}
    297305
    298 scan-build will generate a HTML report of the issues found with a pretty graphical display of the logic followed by the analyser into the $REPORTS directory. Jenkins has a plugin which can publish this HTML report for you per build, for other CIs you'll need to copy the generated files onto a website somewhere e.g. committing them to your repo under gh-pages and pushing them back to github.
    299 
    300 Finally, the clang lint tool (called [http://clang.llvm.org/extra/clang-tidy.html clang-tidy]) is not something I have currently enabled in my own code, but it looks very promising. The following checks are default enabled on clang tidy 3.6:
    301 
    302 {{{
    303 Enabled checks:
    304     clang-analyzer-core.CallAndMessage
    305     clang-analyzer-core.DivideZero
    306     clang-analyzer-core.DynamicTypePropagation
    307     clang-analyzer-core.NonNullParamChecker
    308     clang-analyzer-core.NullDereference
    309     clang-analyzer-core.StackAddressEscape
    310     clang-analyzer-core.UndefinedBinaryOperatorResult
    311     clang-analyzer-core.VLASize
    312     clang-analyzer-core.builtin.BuiltinFunctions
    313     clang-analyzer-core.builtin.NoReturnFunctions
    314     clang-analyzer-core.uninitialized.ArraySubscript
    315     clang-analyzer-core.uninitialized.Assign
    316     clang-analyzer-core.uninitialized.Branch
    317     clang-analyzer-core.uninitialized.CapturedBlockVariable
    318     clang-analyzer-core.uninitialized.UndefReturn
    319     clang-analyzer-cplusplus.NewDelete
    320     clang-analyzer-cplusplus.NewDeleteLeaks
    321     clang-analyzer-deadcode.DeadStores
    322     clang-analyzer-llvm.Conventions
    323     clang-analyzer-security.FloatLoopCounter
    324     clang-analyzer-security.insecureAPI.UncheckedReturn
    325     clang-analyzer-security.insecureAPI.getpw
    326     clang-analyzer-security.insecureAPI.gets
    327     clang-analyzer-security.insecureAPI.mkstemp
    328     clang-analyzer-security.insecureAPI.mktemp
    329     clang-analyzer-security.insecureAPI.rand
    330     clang-analyzer-security.insecureAPI.strcpy
    331     clang-analyzer-security.insecureAPI.vfork
    332     clang-analyzer-unix.API
    333     clang-analyzer-unix.Malloc
    334     clang-analyzer-unix.MallocSizeof
    335     clang-analyzer-unix.MismatchedDeallocator
    336     clang-analyzer-unix.cstring.BadSizeArg
    337     clang-analyzer-unix.cstring.NullArg
    338 }}}
    339 
    340 I also see some default disabled checks which might be interesting:
    341 
    342 {{{
    343     clang-analyzer-alpha.core.BoolAssignment
    344     clang-analyzer-alpha.core.CallAndMessageUnInitRefArg
    345     clang-analyzer-alpha.core.CastSize
    346     clang-analyzer-alpha.core.CastToStruct
    347     clang-analyzer-alpha.core.FixedAddr
    348     clang-analyzer-alpha.core.IdenticalExpr
    349     clang-analyzer-alpha.core.PointerArithm
    350     clang-analyzer-alpha.core.PointerSub
    351     clang-analyzer-alpha.core.SizeofPtr
    352     clang-analyzer-alpha.core.TestAfterDivZero
    353     clang-analyzer-alpha.cplusplus.VirtualCall
    354     clang-analyzer-alpha.deadcode.UnreachableCode
    355     misc-argument-comment
    356     misc-bool-pointer-implicit-conversion
    357     misc-swapped-arguments
    358     misc-undelegated-constructor
    359     misc-uniqueptr-reset-release
    360     misc-unused-raii
    361     misc-use-override
    362     readability-braces-around-statements
    363     readability-function-size
    364     readability-redundant-smartptr-get
    365 }}}
    366 
     306clang-tidy is quite fast, so I run that first and if it generates anything at all then we halt. You will note I enable all checks minus ones I really don't think important, and because the `-header-filter` regex option doesn't appear to accept negative lookahead I have to whitelist via append into the clang-tidy-warnings.txt file. I found clang-tidy to be very useful indeed for catching silly things like forgetting to put override or final on virtual functions, or forgetting to set noexcept on move constructors and assignment operators, so it's well worth running.
     307
     308scan-build will run the static analyser and generate a HTML report of the issues found with a pretty graphical display of the logic followed by the analyser into the $REPORTS directory. Jenkins has a plugin which can publish this HTML report for you per build, for other CIs you'll need to copy the generated files onto a website somewhere e.g. committing them to your repo under gh-pages and pushing them back to github.
    367309
    368310== 6. QUALITY/SAFETY: Strongly consider running a per-commit pass of your unit tests under both valgrind and the runtime sanitisers ==