Skip to content

Latest commit

 

History

History
422 lines (235 loc) · 22.1 KB

expressions.md

File metadata and controls

422 lines (235 loc) · 22.1 KB
  • 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