-
Notifications
You must be signed in to change notification settings - Fork 0
Static Analysis
We have a .clangd file mirroring clang tidy check.
On top of that, we use clangd on our IDE (vscode or nvim) as a linter.
We didn't manage to get reliable lints on vscode for unused headers. An alternative would be Include What You Use - IWYU
-
clang-tidy is a static analysis tool which goes beyond a format linter and can help finding bugs and performance issue. The main check categories are
- bugprone : suspicious casts, invalid/dangling pointers...
- performance : unnecessary copy, ...
- readability : naming, const correctness
- best practices from C++ Core Guidelines
-
As for clang-format, it can be configured via a
.clang-tidyfile at the root of the project -
Desactivate a check
- globally by adding
-prefix to the check in.clang-tidy - once inline by adding a
// NOLINT(<rule>)in the code
- globally by adding
clang-tidy is slower than cppcheck but is more accurate
clang-tidy and clangd need a compilation database compile_commands.json to trace back the flags and includes used at each file compilation
pip install scan-build
# add PATH - update path with something like /home/<user>/.local/bin'
export PATH=$PATH:<path>Generate the compilation database with intercept-build make <target>
-
bugprone-assignment-in-if-conditionlink -
bugprone-bool-pointer-implicit-conversionlink -
bugprone-branch-clonelink -
bugprone-casting-through-voidlink -
bugprone-chained-comparisonlink -
!
bugprone-copy-constructor-initlink -
!
bugprone-dangling-handlelink -
!
bugprone-derived-method-shadowing-base-methodlink -
bugprone-dynamic-static-initializerslink -
?
bugprone-easily-swappable-parameterslink -
!
bugprone-empty-catchlink -
!
bugprone-exception-escapelink -
bugprone-fold-init-typelink -
bugprone-forward-declaration-namespacelink -
??
bugprone-forwarding-reference-overloadlink // c++ 11 probably -
bugprone-implicit-widening-of-multiplication-resultlink -
bugprone-inaccurate-eraselink -
?
bugprone-inc-dec-in-conditionslink -
bugprone-incorrect-roundingslink -
!
bugprone-infinite-looplink -
bugprone-integer-divisionlink -
bugprone-invalid-enum-default-initializationlink -
!
bugprone-macro-parentheseslink -
!
bugprone-misleading-setter-of-referencelink -
bugprone-misplaced-widening-castlink -
bugprone-multi-level-implicit-pointer-conversionlink -
bugprone-multiple-new-in-one-expressionlink -
bugprone-multiple-statement-macrolink -
!
bugprone-narrowing-conversionslink -
https://clang.llvm.org/extra/clang-tidy/checks/bugprone/non-zero-enum-to-bool-conversion.htmllink -
??
bugprone-nondeterministic-pointer-iteration-orderlink -
!
bugprone-not-null-terminated-resultlink -
!
bugprone-parent-virtual-calllink -
bugprone-pointer-arithmetic-on-polymorphic-objectlink -
bugprone-redundant-branch-conditionlink -
bugprone-reserved-identifierlink -
!
bugprone-return-const-ref-from-parameterlink -
??
bugprone-signal-handlerlink -
bugprone-signed-char-misuselink -
bugprone-sizeof-containerlink -
bugprone-sizeof-expressionlink -
bugprone-standalone-emptylink -
!
bugprone-string-constructorlink -
bugprone-string-literal-with-embedded-nullink -
bugprone-suspicious-enum-usagelink -
bugprone-suspicious-includelink -
bugprone-suspicious-memset-usagelink -
bugprone-suspicious-missing-commalink -
bugprone-suspicious-semicolonlink -
bugprone-suspicious-string-comparelink -
!
bugprone-swapped-argumentslink -
bugprone-switch-missing-default-caselink -
bugprone-terminating-continuelink -
bugprone-throw-keyword-missinglink -
!
bugprone-too-small-loop-variablelink -
bugprone-unchecked-string-to-number-conversionlink -
bugprone-undefined-memory-manipulationlink -
!
bugprone-unhandled-self-assignmentlink -
bugprone-unintended-char-ostream-outputlink -
!
bugprone-unsafe-functionslink -
!
bugprone-unused-local-non-trivial-variablelink -
??
bugprone-unused-raiilink -
?
bugprone-unused-return-valuelink -
bugprone-virtual-near-misslink
- !
cppcoreguidelines-avoid-const-or-ref-data-memberslink - !
cppcoreguidelines-avoid-non-const-global-variableslink - !
cppcoreguidelines-init-variableslink - !
cppcoreguidelines-macro-usagelink - !!
cppcoreguidelines-no-malloclink - !
cppcoreguidelines-prefer-member-initializerlink - ??
cppcoreguidelines-pro-bounds-array-to-pointer-decaylink - ?
cppcoreguidelines-pro-bounds-avoid-unchecked-container-accesslink -
cppcoreguidelines-pro-bounds-constant-array-indexlink - ?
cppcoreguidelines-pro-bounds-pointer-arithmeticlink -
cppcoreguidelines-pro-type-const-castlink - !
cppcoreguidelines-pro-type-cstyle-castlink - !
cppcoreguidelines-pro-type-member-initlink - ?
cppcoreguidelines-pro-type-reinterpret-castlink - !
cppcoreguidelines-pro-type-static-cast-downcastlink - ??
cppcoreguidelines-slicinglink - ?
cppcoreguidelines-special-member-functionslink - ??
cppcoreguidelines-use-enum-classlink -
cppcoreguidelines-virtual-class-destructorlink
- dereferencing a possibly null pointer
core.NullDereference
// wrong ❌
int* p = NULL;
int x = *p;-
constructing from null pointer
cpluplus.StringCheckerlink -
leaks
cplusplus.NewDeletelinkcplusplus.NewDeleteLeakslinkcplusplus.ArrayDeletelink ... -
unitialized variables
core.UndefinedBinaryOperatorResultcore.UndefinedAssignmentcore.uninitialized.ArraySubscriptlinkcore.uninitialized.Assignlinkcore.uninitialized.Branchlinkcore.CallAndMessagelinkcore.uninitialized.NewArraySizelink ...
// wrong ❌
int x;
if (x > 0) {...}- using a variable after free
cplusplus.NewDeleteLeakslink
// wrong ❌
int* p = new int(5);
delete p;
std::cout << *p;-
fd leaks
unix.Stream -
ignored return values ??
bugprone-ignored-return-value
// wrong ❌
write(fd, buf, len); // how do we know if all bytes are read ?
// good ✅- division by zero
core.DivideZerolink - other operations
core.UndefinedBinaryOperatorResultlink - shifting too many bits
- numeric types overflow
- variable shadowing -> use namespaces
- const correctness
performance-unnecessary-copy-initialization
// wrong ❌
std::string msg = getMessage(); // copies result unnecessarily
// good ✅ = move if function returns by value
std::string msg = std::move(getMessage());- unused functions, variable
readability-container-size-empty
// wrong ❌
if (v.size() == 0) { /* ... */ }
// good ✅
if (v.empty()) { /* ... */ }- dead code
deadCode.DeadStoreslink
readability-implicit-bool-conversion
// wrong ❌
if (x) { /* ... */ }
// good ✅
if (x != 0) { /* ... */ }