- Flag loop variable declared outside a loop and not used after the loop
- Flag when expensive resources, such as file handles and locks are not used for N-lines (for some suitable N)
clang-tidy: readability-function-size
- Flag loop variables declared before the loop and not used after the loop
- (hard) Flag loop variables declared before the loop and used after the loop for an unrelated purpose.
C++17 enforcement (if using a C++17 compiler)
- Flag selection/loop variables declared before the body and not used after the body
- (hard) Flag selection/loop variables declared before the body and used after the body for an unrelated purpose.
no enforcement
- Check length of local and non-local names. Also take function length into account.
no enforcement
- Check names against a list of known confusing letter and digit combinations.
- Flag a declaration of a variable, function, or enumerator that hides a class or enumeration declared in the same scope
no enforcement
- Flag all uses of ALL CAPS. For older code, accept ALL CAPS for macro names and flag all non-ALL-CAPS macro names.
no enforcement
- Flag variable and constant declarations with multiple declarators (e.g., int* p, q;)
clang-format
- Flag redundant repetition of type names in a declaration.
clang-tidy: modernize-use-auto
- Flag reuse of a name in nested local scopes
- Flag reuse of a member name as a local variable in a member function
- Flag reuse of a global name as a local variable or a member name
- Flag reuse of a base class member name in a derived class (except for function names)
no enforcement, maybe shadow declarations?
- Flag every uninitialized variable. Don't flag variables of user-defined types with default constructors.
- Check that an uninitialized buffer is written into immediately after declaration. Passing an uninitialized variable as a reference to non-const argument can be assumed to be a write into the variable.
no enforcement
- Flag declarations that are distant from their first use.
no enforcement
- Flag declarations with default initialization that are assigned to before they are first read.
- Flag any complicated computation after an uninitialized variable and before its use.
no enforcement
- Tricky.
- Don't flag uses of = for simple initializers.
- Look for = after auto has been seen.
no enforcement
- Look for raw pointers that are targets of new, malloc(), or functions that may return such pointers.
clang-tidy: cppcoreguidelines-owning-memory
- Look to see if a variable is actually mutated, and flag it if not. Unfortunately, it may be impossible to detect when a non-const was not intended to vary (vs when it merely did not vary).
no enforcement
- Flag recycled variables.
no enforcement
- Flag arrays with non-constant bounds (C-style VLAs)
- Flag arrays with non-local constant bounds
no enforcement
- Hard. At best a heuristic. Look for an uninitialized variable followed by a loop assigning to it.
no enforcement
- Scream when you see a macro that isn't just used for source control (e.g., #ifdef)
no enforcement
- Scream when you see a macro that isn't just used for source control (e.g., #ifdef)
no enforcement
- Scream when you see a lower case macro.
clang-tidy: readability-identifier-naming
- Warn against short macro names.
no enforcement
- Flag definitions of C-style variadic functions.
- Flag #include and #include <stdarg.h>
clang-tidy: cppcoreguidelines-pro-type-vararg
- side effects: side effects on multiple non-local variables (for some definition of non-local) can be suspect, especially if the side effects are in separate subexpressions
- writes to aliased variables
- more than N operators (and what should N be?)
- reliance of subtle precedence rules
- uses undefined behavior (can we catch all undefined behavior?)
- implementation defined behavior?
no enforcement
- Flag combinations of bitwise-logical operators and other operators.
- Flag assignment operators not as the leftmost operator.
no enforcement
- Flag any arithmetic operation on an expression of pointer type that results in a value of pointer type.
- Flag any indexing expression on an expression or variable of array type (either static array or std::array) where the indexer is not a compile-time constant expression with a value between 0 or and the upper bound of the array.
- Flag any expression that would rely on implicit conversion of an array type to a pointer type.
clang-tidy: cppcoreguidelines-pro-bounds-
- Can be detected by a good analyzer.
no enforcement
- Can be detected by a good analyzer.
no enforcement
- Flag literals in code. Give a pass to 0, 1, nullptr, \n, "", and others on a positive list.
no enforcement
A good analyzer can detect all narrowing conversions. However, flagging all narrowing conversions will lead to a lot of false positives. Suggestions:
- flag all floating-point to integer conversions (maybe only float->char and double->int. Here be dragons! we need data)
- flag all long->char (I suspect int->char is very common. Here be dragons! we need data)
- consider narrowing conversions for function arguments especially suspect
clang-sanitizers: -fsanitize=implicit-integer-truncation
- Flag uses of 0 and NULL for pointers. The transformation may be helped by simple program transformation.
clang-tidy: modernize-use-nullptr
- Force the elimination of C-style casts
- Warn if there are many functional style casts (there is an obvious problem in quantifying 'many')
- The type profile bans reinterpret_cast.
- Warn against identity casts between pointer types, where the source and target types are the same (#Pro-type-identitycast)
- Warn if a pointer cast could be implicit
clang-tidy: cppcoreguidelines-pro-type-const-cast, cppcoreguidelines-pro-type-cstyle-cast, cppcoreguidelines-pro-type-reinterpret-cast, cppcoreguidelines-pro-type-static-cast-downcast
- Flag C-style and functional casts.
- The type profile bans reinterpret_cast.
- The type profile warns when using static_cast between arithmetic types.
clang-tidy: same as in ES.48
core-check: C26475 NO_FUNCTION_STYLE_CASTS
- Flag const_casts.
- This rule is part of the type-safety profile for the related Profile.
clang-tidy: cppcoreguidelines-pro-type-const-cast, cppcoreguidelines-pro-type-cstyle-cast
- Look for explicit range checks and heuristically suggest alternatives.
clang-tidy: modernize-loop-convert
- Flag use of std::move(x) where x is an rvalue or the language will already treat it as an rvalue, including return std::move(local_variable); and std::move(f()) on a function that returns by value.
- Flag functions taking an S&& parameter if there is no const S& overload to take care of lvalues.
- Flag a std::moves argument passed to a parameter, except when the parameter type is one of the following: an X&& rvalue reference; a T&& forwarding reference where T is a template parameter type; or by value and the type is move-only.
- Flag when std::move is applied to a forwarding reference (T&& where T is a template parameter type). Use std::forward instead.
- Flag when std::move is applied to other than an rvalue reference. (More general case of the previous rule to cover the non-forwarding cases.)
- Flag when std::forward is applied to an rvalue reference (X&& where X is a concrete type). Use std::move instead.
- Flag when std::forward is applied to other than a forwarding reference. (More general case of the previous rule to cover the non-moving cases.)
- Flag when an object is potentially moved from and the next operation is a const operation; there should first be an intervening non-const operation, ideally assignment, to first reset the object's value.
no enforcement
- Flag naked news and naked deletes
clang-tidy: cppcoreguidelines-owning-memory
- if the new and the delete is in the same scope, mistakes can be flagged.
- if the new and the delete are in a constructor/destructor pair, mistakes can be flagged.
clang-static-analyzer: cplusplus.NewDelete
clang-tidy: clang-analyzer-cplusplus.NewDelete
- Warn against slicing.
clang-tidy: cppcoreguidelines-slicing
core-check: C26437 DONT_SLICE
- Flag the C-style (T)e and functional-style T(e) casts.
no enforcement?, castingwarnings are done
- Flag a dereference of a pointer that points to an object that has gone out of scope
- Flag a dereference of a pointer that may have been invalidated by assigning a nullptr
- Flag a dereference of a pointer that may have been invalidated by a delete
- Flag a dereference to a pointer to a container element that may have been invalidated by dereference
clang-tidy: bugprone-use-after-move, clang-analyzer-core.NullDereference
Adress Sanitizer, Memory Sanitizer, Thread Sanitizer, Undefined Behaviour
Sanitizer
- Flag if-then-else chains that check against constants (only).
no enforcement
- Look at loops, if a traditional loop just looks at each element of a sequence, and there are no side effects on what it does with the elements, rewrite the loop to a ranged-for loop.
clang-tidy: modernize-loop-convert
- Flag actions in for-initializers and for-increments that do not relate to the for-condition.
no enforcement
- Warn when a variable modified inside the for-statement is declared outside the loop and not being used outside the loop.
no enforcement
- Flag do-statements.
no enforcement
- Flag goto. Better still flag all gotos that do not jump from a nested loop to the statement immediately after a nest of loops.
core-check: C26438 NO_GOTO
clang-tidy: cppcoreguidelines-avoid-goto
- Flag all fallthroughs from non-empty cases.
no enforcement
- Flag switch-statements over an enumeration that don't handle all enumerators and do not have a default. This may yield too many false positives in some code bases; if so, flag only switches that handle most but not all cases (that was the strategy of the very first C++ compiler).
clang-diagnostics: -Wswitch
- Flag statements that are just a temporary
no enforcement
- Flag empty statements that are not blocks and don't contain comments.
no enforcement
- Flag variables that are potentially updated (have a non-const use) in both the loop control iteration-expression and the loop body.
no enforcement
- Easy, just check for redundant use of != and == in conditions.
clang-tidy: misc-redundant-expression, readability-simplify-boolean-expr
- Compilers already know and sometimes warn.
clang-sanitizers: -fsanitize=implicit-integer-sign-change
in essence the same rule as ES.102
- Just about impossible in general because of the use of unsigned subscripts in the standard library
clang-tidy: hicpp-signed-bitwise
- Flag mixed signed and unsigned arithmetic
- Flag results of unsigned arithmetic assigned to or printed as signed.
- Flag unsigned literals (e.g. -2) used as container subscripts.
clang-sanitizers: -fsanitize=integer
- no static enforcement!
Undefined Behaviour Sanitizer
- no static enforcement!
Undefined Behaviour Sanitizer
- Flag division by an integral value that could be zero
clang-static-analyzer: core.DivideZero
clang-tidy: clang-analyzer-code.DivideZero
Undefined Behaviour Sanizier
- Hard: there is a lot of code using unsigned and we don't offer a practical positive number type.
no enforcement
- Very tricky as long as the standard-library containers get it wrong.
no enforcement