[Clang-tidy] Fix some checks documentation style.

Differential revision: https://reviews.llvm.org/D23894

llvm-svn: 279846
This commit is contained in:
Eugene Zelenko 2016-08-26 17:46:51 +00:00
parent bc1701c7fb
commit 8e8fa78821
30 changed files with 188 additions and 174 deletions

View File

@ -8,7 +8,7 @@ verify the validity of the conversion, such as ``atoi()`` or ``scanf()``. It
does not flag calls to ``strtol()``, or other, related conversion functions that does not flag calls to ``strtol()``, or other, related conversion functions that
do perform better error checking. do perform better error checking.
.. code:: c .. code-block:: c
#include <stdlib.h> #include <stdlib.h>

View File

@ -5,19 +5,21 @@ cppcoreguidelines-slicing
Flags slicing of member variables or vtable. Slicing happens when copying a Flags slicing of member variables or vtable. Slicing happens when copying a
derived object into a base object: the members of the derived object (both derived object into a base object: the members of the derived object (both
member variables and virtual member functions) will be discarded. member variables and virtual member functions) will be discarded. This can be
This can be misleading especially for member function slicing, for example: misleading especially for member function slicing, for example:
.. code:: c++ .. code-block:: c++
struct B { int a; virtual int f(); }; struct B { int a; virtual int f(); };
struct D : B { int b; int f() override; }; struct D : B { int b; int f() override; };
void use(B b) { // Missing reference, intended ?
b.f(); // Calls B::f.
}
D d;
use(d); // Slice.
See the relevant CppCoreGuidelines sections for details: void use(B b) { // Missing reference, intended?
b.f(); // Calls B::f.
}
D d;
use(d); // Slice.
See the relevant C++ Core Guidelines sections for details:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es63-dont-slice https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es63-dont-slice
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c145-access-polymorphic-objects-through-pointers-and-references https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c145-access-polymorphic-objects-through-pointers-and-references

View File

@ -5,14 +5,13 @@ google-build-using-namespace
Finds ``using namespace`` directives. Finds ``using namespace`` directives.
https://google.github.io/styleguide/cppguide.html#Namespaces The check implements the following rule of the
`Google C++ Style Guide <https://google.github.io/styleguide/cppguide.html#Namespaces>`_:
The check implements the following rule of the Google C++ Style Guide:
You may not use a using-directive to make all names from a namespace You may not use a using-directive to make all names from a namespace
available. available.
.. code:: c++ .. code-block:: c++
// Forbidden -- This pollutes the namespace. // Forbidden -- This pollutes the namespace.
using namespace foo; using namespace foo;

View File

@ -5,10 +5,10 @@ google-runtime-member-string-references
Finds members of type ``const string&``. Finds members of type ``const string&``.
const string reference members are generally considered unsafe as they can const string reference members are generally considered unsafe as they can be
be created from a temporary quite easily. created from a temporary quite easily.
.. code:: c++ .. code-block:: c++
struct S { struct S {
S(const string &Str) : Str(Str) {} S(const string &Str) : Str(Str) {}
@ -16,9 +16,8 @@ be created from a temporary quite easily.
}; };
S instance("string"); S instance("string");
In the constructor call a string temporary is created from ``const char *`` In the constructor call a string temporary is created from ``const char *`` and
and destroyed immediately after the call. This leaves around a dangling destroyed immediately after the call. This leaves around a dangling reference.
reference.
This check emit warnings for both ``std::string`` and ``::string`` const This check emit warnings for both ``std::string`` and ``::string`` const
reference members. reference members.

View File

@ -8,10 +8,9 @@ Checks for conditions based on implicit conversion from a ``bool`` pointer to
Example: Example:
.. code:: c++ .. code-block:: c++
bool *p; bool *p;
if (p) { if (p) {
// Never used in a pointer-specific way. // Never used in a pointer-specific way.
} }

View File

@ -14,14 +14,14 @@ through:
initial value, so trucation wil happen at every application of ``operator+`` initial value, so trucation wil happen at every application of ``operator+``
and the result will be `0`, which might not be what the user expected. and the result will be `0`, which might not be what the user expected.
.. code:: c++ .. code-block:: c++
auto a = {0.5f, 0.5f, 0.5f, 0.5f}; auto a = {0.5f, 0.5f, 0.5f, 0.5f};
return std::accumulate(std::begin(a), std::end(a), 0); return std::accumulate(std::begin(a), std::end(a), 0);
- Overflow: The following code also returns `0`. - Overflow: The following code also returns `0`.
.. code:: c++ .. code-block:: c++
auto a = {65536LL * 65536 * 65536}; auto a = {65536LL * 65536 * 65536};
return std::accumulate(std::begin(a), std::end(a), 0); return std::accumulate(std::begin(a), std::end(a), 0);

View File

@ -9,7 +9,7 @@ The check inspects all unused forward declarations and checks if there is any
declaration/definition with the same name existing, which could indicate that declaration/definition with the same name existing, which could indicate that
the forward declaration is in a potentially wrong namespace. the forward declaration is in a potentially wrong namespace.
.. code:: c++ .. code-block:: c++
namespace na { struct A; } namespace na { struct A; }
namespace nb { struct A {}; } namespace nb { struct A {}; }

View File

@ -11,7 +11,7 @@ than the pointee.
For instance, in the following code, the resulting type is ``int *`` ``const`` For instance, in the following code, the resulting type is ``int *`` ``const``
rather than ``const int *``: rather than ``const int *``:
.. code:: c++ .. code-block:: c++
typedef int *int_ptr; typedef int *int_ptr;
void f(const int_ptr ptr); void f(const int_ptr ptr);

View File

@ -5,17 +5,18 @@ misc-move-const-arg
The check warns The check warns
- if ``std::move()`` is called with a constant argument, - if ``std::move()`` is called with a constant argument,
- if ``std::move()`` is called with an argument of a trivially-copyable type,
or - if ``std::move()`` is called with an argument of a trivially-copyable type,
- if the result of ``std::move()`` is passed as a const reference argument.
- if the result of ``std::move()`` is passed as a const reference argument.
In all three cases, the check will suggest a fix that removes the In all three cases, the check will suggest a fix that removes the
``std::move()``. ``std::move()``.
Here are examples of each of the three cases: Here are examples of each of the three cases:
.. code:: c++ .. code-block:: c++
const string s; const string s;
return std::move(s); // Warning: std::move of the const variable has no effect return std::move(s); // Warning: std::move of the const variable has no effect

View File

@ -3,14 +3,14 @@
misc-multiple-statement-macro misc-multiple-statement-macro
============================= =============================
Detect multiple statement macros that are used in unbraced conditionals. Detect multiple statement macros that are used in unbraced conditionals. Only
Only the first statement of the macro will be inside the conditional and the other ones will be executed unconditionally. the first statement of the macro will be inside the conditional and the other
ones will be executed unconditionally.
Example: Example:
.. code:: c++ .. code-block:: c++
#define INCREMENT_TWO(x, y) (x)++; (y)++ #define INCREMENT_TWO(x, y) (x)++; (y)++
if (do_increment) if (do_increment)
INCREMENT_TWO(a, b); // `(b)++;` will be executed unconditionally. INCREMENT_TWO(a, b); // (b)++ will be executed unconditionally.

View File

@ -9,7 +9,7 @@ object is compare to an object with integral type.
Examples: Examples:
.. code:: c++ .. code-block:: c++
char* ptr; char* ptr;
if ((ptr = malloc(...)) < nullptr) // Pointer comparison with operator '<' if ((ptr = malloc(...)) < nullptr) // Pointer comparison with operator '<'

View File

@ -6,14 +6,18 @@ misc-redundant-expression
Detect redundant expressions which are typically errors due to copy-paste. Detect redundant expressions which are typically errors due to copy-paste.
Depending on the operator expressions may be Depending on the operator expressions may be
* redundant,
* always be `true`, - redundant,
* always be `false`,
* always be a constant (zero or one) - always be ``true``,
- always be ``false``,
- always be a constant (zero or one).
Example: Example:
.. code:: c++ .. code-block:: c++
((x+1) | (x+1)) // (x+1) is redundant ((x+1) | (x+1)) // (x+1) is redundant
(p->x == p->x) // always true (p->x == p->x) // always true

View File

@ -12,7 +12,7 @@ method are considered containers, with the exception of ``std::bitset`` and
Examples: Examples:
.. code:: c++ .. code-block:: c++
std::string s; std::string s;
int a = 47 + sizeof(s); // warning: sizeof() doesn't return the size of the container. Did you mean .size()? int a = 47 + sizeof(s); // warning: sizeof() doesn't return the size of the container. Did you mean .size()?
@ -24,4 +24,3 @@ Examples:
std::array<int, 3> std_array; std::array<int, 3> std_array;
int d = sizeof(std_array); // no warning, probably intended. int d = sizeof(std_array); // no warning, probably intended.

View File

@ -9,28 +9,28 @@ The ``sizeof`` operator yields the size (in bytes) of its operand, which may be
an expression or the parenthesized name of a type. Misuse of this operator may an expression or the parenthesized name of a type. Misuse of this operator may
be leading to errors and possible software vulnerabilities. be leading to errors and possible software vulnerabilities.
Suspicious usage of 'sizeof(K)' Suspicious usage of 'sizeof(K)'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -------------------------------
A common mistake is to query the ``sizeof`` of an integer literal. This is A common mistake is to query the ``sizeof`` of an integer literal. This is
equivalent to query the size of its type (probably ``int``). The intent of the equivalent to query the size of its type (probably ``int``). The intent of the
programmer was probably to simply get the integer and not its size. programmer was probably to simply get the integer and not its size.
.. code:: c++ .. code-block:: c++
#define BUFLEN 42 #define BUFLEN 42
char buf[BUFLEN]; char buf[BUFLEN];
memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int) memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int)
Suspicious usage of 'sizeof(this)' Suspicious usage of 'sizeof(this)'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------------------------------
The ``this`` keyword is evaluated to a pointer to an object of a given type. The ``this`` keyword is evaluated to a pointer to an object of a given type.
The expression ``sizeof(this)`` is returning the size of a pointer. The The expression ``sizeof(this)`` is returning the size of a pointer. The
programmer most likely wanted the size of the object and not the size of the programmer most likely wanted the size of the object and not the size of the
pointer. pointer.
.. code:: c++ .. code-block:: c++
class Point { class Point {
[...] [...]
@ -38,29 +38,29 @@ pointer.
[...] [...]
}; };
Suspicious usage of 'sizeof(char*)' Suspicious usage of 'sizeof(char*)'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -----------------------------------
There is a subtle difference between declaring a string literal with There is a subtle difference between declaring a string literal with
``char* A = ""`` and ``char A[] = ""``. The first case has the type ``char*`` ``char* A = ""`` and ``char A[] = ""``. The first case has the type ``char*``
instead of the aggregate type ``char[]``. Using ``sizeof`` on an object declared instead of the aggregate type ``char[]``. Using ``sizeof`` on an object declared
with ``char*`` type is returning the size of a pointer instead of the number of with ``char*`` type is returning the size of a pointer instead of the number of
characters (bytes) in the string literal. characters (bytes) in the string literal.
.. code:: c++ .. code-block:: c++
const char* kMessage = "Hello World!"; // const char kMessage[] = "..."; const char* kMessage = "Hello World!"; // const char kMessage[] = "...";
void getMessage(char* buf) { void getMessage(char* buf) {
memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*) memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*)
} }
Suspicious usage of 'sizeof(A*)' Suspicious usage of 'sizeof(A*)'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------------------------
A common mistake is to compute the size of a pointer instead of its pointee. A common mistake is to compute the size of a pointer instead of its pointee.
These cases may occur because of explicit cast or implicit conversion. These cases may occur because of explicit cast or implicit conversion.
.. code:: c++ .. code-block:: c++
int A[10]; int A[10];
memset(A, 0, sizeof(A + 0)); memset(A, 0, sizeof(A + 0));
@ -68,67 +68,65 @@ These cases may occur because of explicit cast or implicit conversion.
struct Point point; struct Point point;
memset(point, 0, sizeof(&point)); memset(point, 0, sizeof(&point));
Suspicious usage of 'sizeof(...)/sizeof(...)' Suspicious usage of 'sizeof(...)/sizeof(...)'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------------------------------------
Dividing ``sizeof`` expressions is typically used to retrieve the number of Dividing ``sizeof`` expressions is typically used to retrieve the number of
elements of an aggregate. This check warns on incompatible or suspicious cases. elements of an aggregate. This check warns on incompatible or suspicious cases.
In the following example, the entity has 10-bytes and is incompatible with the In the following example, the entity has 10-bytes and is incompatible with the
type ``int`` which has 4 bytes. type ``int`` which has 4 bytes.
.. code:: c++ .. code-block:: c++
char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10 char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10
void getMessage(char* dst) { void getMessage(char* dst) {
memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes] memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes]
} }
In the following example, the expression ``sizeof(Values)`` is returning the In the following example, the expression ``sizeof(Values)`` is returning the
size of ``char*``. One can easily be fooled by its declaration, but in parameter size of ``char*``. One can easily be fooled by its declaration, but in parameter
declaration the size '10' is ignored and the function is receiving a ``char*``. declaration the size '10' is ignored and the function is receiving a ``char*``.
.. code:: c++ .. code-block:: c++
char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
return CompareArray(char Values[10]) { return CompareArray(char Values[10]) {
return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*] return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*]
} }
Suspicious 'sizeof' by 'sizeof' expression Suspicious 'sizeof' by 'sizeof' expression
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------------------------
Multiplying ``sizeof`` expressions typically makes no sense and is probably a Multiplying ``sizeof`` expressions typically makes no sense and is probably a
logic error. In the following example, the programmer used ``*`` instead of logic error. In the following example, the programmer used ``*`` instead of
``/``. ``/``.
.. code:: c++ .. code-block:: c++
const char kMessage[] = "Hello World!"; const char kMessage[] = "Hello World!";
void getMessage(char* buf) { void getMessage(char* buf) {
memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char) memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char)
} }
This check may trigger on code using the arraysize macro. The following code is This check may trigger on code using the arraysize macro. The following code is
working correctly but should be simplified by using only the ``sizeof`` working correctly but should be simplified by using only the ``sizeof``
operator. operator.
.. code:: c++ .. code-block:: c++
extern Object objects[100]; extern Object objects[100];
void InitializeObjects() { void InitializeObjects() {
memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects) memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects)
} }
Suspicious usage of 'sizeof(sizeof(...))' Suspicious usage of 'sizeof(sizeof(...))'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -----------------------------------------
Getting the ``sizeof`` of a ``sizeof`` makes no sense and is typically an error Getting the ``sizeof`` of a ``sizeof`` makes no sense and is typically an error
hidden through macros. hidden through macros.
.. code:: c++ .. code-block:: c++
#define INT_SZ sizeof(int) #define INT_SZ sizeof(int)
int buf[] = { 42 }; int buf[] = { 42 };

View File

@ -7,13 +7,13 @@ The check finds assignments of an integer to ``std::basic_string<CharT>``
(``std::string``, ``std::wstring``, etc.). The source of the problem is the (``std::string``, ``std::wstring``, etc.). The source of the problem is the
following assignment operator of ``std::basic_string<CharT>``: following assignment operator of ``std::basic_string<CharT>``:
.. code:: c++ .. code-block:: c++
basic_string& operator=( CharT ch ); basic_string& operator=( CharT ch );
Numeric types can be implicitly casted to character types. Numeric types can be implicitly casted to character types.
.. code:: c++ .. code-block:: c++
std::string s; std::string s;
int x = 5965; int x = 5965;
@ -22,7 +22,7 @@ Numeric types can be implicitly casted to character types.
Use the appropriate conversion functions or character literals. Use the appropriate conversion functions or character literals.
.. code:: c++ .. code-block:: c++
std::string s; std::string s;
int x = 5965; int x = 5965;
@ -31,7 +31,7 @@ Use the appropriate conversion functions or character literals.
In order to suppress false positives, use an explicit cast. In order to suppress false positives, use an explicit cast.
.. code:: c++ .. code-block:: c++
std::string s; std::string s;
s = static_cast<char>(6); s = static_cast<char>(6);

View File

@ -6,32 +6,30 @@ misc-string-literal-with-embedded-nul
Finds occurences of string literal with embedded NUL character and validates Finds occurences of string literal with embedded NUL character and validates
their usage. their usage.
Invalid escaping Invalid escaping
^^^^^^^^^^^^^^^^ ----------------
Special characters can be escaped within a string literal by using their Special characters can be escaped within a string literal by using their
hexadecimal encoding like ``\x42``. A common mistake is to escape them hexadecimal encoding like ``\x42``. A common mistake is to escape them
like this ``\0x42`` where the ``\0`` stands for the NUL character. like this ``\0x42`` where the ``\0`` stands for the NUL character.
.. code:: c++ .. code-block:: c++
const char* Example[] = "Invalid character: \0x12 should be \x12"; const char* Example[] = "Invalid character: \0x12 should be \x12";
const char* Bytes[] = "\x03\0x02\0x01\0x00\0xFF\0xFF\0xFF"; const char* Bytes[] = "\x03\0x02\0x01\0x00\0xFF\0xFF\0xFF";
Truncated literal Truncated literal
^^^^^^^^^^^^^^^^^ -----------------
String-like classes can manipulate strings with embedded NUL as they are String-like classes can manipulate strings with embedded NUL as they are keeping
keeping track of the bytes and the length. This is not the case for a track of the bytes and the length. This is not the case for a ``char*``
``char*`` (NUL-terminated) string. (NUL-terminated) string.
A common mistake is to pass a string-literal with embedded NUL to a string A common mistake is to pass a string-literal with embedded NUL to a string
constructor expecting a NUL-terminated string. The bytes after the first NUL constructor expecting a NUL-terminated string. The bytes after the first NUL
character are truncated. character are truncated.
.. code:: c++ .. code-block:: c++
std::string str("abc\0def"); // "def" is truncated std::string str("abc\0def"); // "def" is truncated
str += "\0"; // This statement is doing nothing str += "\0"; // This statement is doing nothing

View File

@ -8,33 +8,31 @@ This check is valid in C and C++.
Checks for calls with implicit comparator and proposed to explicitly add it. Checks for calls with implicit comparator and proposed to explicitly add it.
.. code:: c++ .. code-block:: c++
if (strcmp(...)) // Implicitly compare to zero if (strcmp(...)) // Implicitly compare to zero
if (!strcmp(...)) // Won't warn if (!strcmp(...)) // Won't warn
if (strcmp(...) != 0) // Won't warn if (strcmp(...) != 0) // Won't warn
Checks that compare function results (i,e, ``strcmp``) are compared to valid Checks that compare function results (i,e, ``strcmp``) are compared to valid
constant. The resulting value is constant. The resulting value is
.. code:: .. code-block::
< 0 when lower than, < 0 when lower than,
> 0 when greater than, > 0 when greater than,
== 0 when equals. == 0 when equals.
A common mistake is to compare the result to '1' or '-1'. A common mistake is to compare the result to `1` or `-1`.
.. code:: c++ .. code-block:: c++
if (strcmp(...) == -1) // Incorrect usage of the returned value. if (strcmp(...) == -1) // Incorrect usage of the returned value.
Additionally, the check warns if the results value is implicitly cast to a Additionally, the check warns if the results value is implicitly cast to a
*suspicious* non-integer type. It's happening when the returned value is used in *suspicious* non-integer type. It's happening when the returned value is used in
a wrong context. a wrong context.
.. code:: c++ .. code-block:: c++
if (strcmp(...) < 0.) // Incorrect usage of the returned value. if (strcmp(...) < 0.) // Incorrect usage of the returned value.

View File

@ -3,15 +3,14 @@
misc-uniqueptr-reset-release misc-uniqueptr-reset-release
============================ ============================
Find and replace ``unique_ptr::reset(release())`` with ``std::move()``. Find and replace ``unique_ptr::reset(release())`` with ``std::move()``.
Example: Example:
.. code:: c++ .. code-block:: c++
std::unique_ptr<Foo> x, y; std::unique_ptr<Foo> x, y;
x.reset(y.release()); -> x = std::move(y); x.reset(y.release()); -> x = std::move(y);
If ``y`` is already rvalue, ``std::move()`` is not added. ``x`` and ``y`` can also If ``y`` is already rvalue, ``std::move()`` is not added. ``x`` and ``y`` can
be ``std::unique_ptr<Foo>*``. also be ``std::unique_ptr<Foo>*``.

View File

@ -3,12 +3,11 @@
misc-unused-raii misc-unused-raii
================ ================
Finds temporaries that look like RAII objects. Finds temporaries that look like RAII objects.
The canonical example for this is a scoped lock. The canonical example for this is a scoped lock.
.. code:: c++ .. code-block:: c++
{ {
scoped_lock(&global_mutex); scoped_lock(&global_mutex);
@ -21,8 +20,11 @@ entered, leaving it unprotected.
We apply a number of heuristics to reduce the false positive count of this We apply a number of heuristics to reduce the false positive count of this
check: check:
* Ignore code expanded from macros. Testing frameworks make heavy use of this. - Ignore code expanded from macros. Testing frameworks make heavy use of this.
* Ignore types with trivial destructors. They are very unlikely to be RAII
objects and there's no difference when they are deleted. - Ignore types with trivial destructors. They are very unlikely to be RAII
* Ignore objects at the end of a compound statement (doesn't change behavior). objects and there's no difference when they are deleted.
* Ignore objects returned from a call.
- Ignore objects at the end of a compound statement (doesn't change behavior).
- Ignore objects returned from a call.

View File

@ -7,8 +7,7 @@ Finds unused ``using`` declarations.
Example: Example:
.. code:: c++ .. code-block:: c++
namespace n { class C; } namespace n { class C; }
using n::C; // Never actually used. using n::C; // Never actually used.

View File

@ -10,13 +10,13 @@ Right now it only handles free functions, not member functions.
Given: Given:
.. code:: c++ .. code-block:: c++
int add(int x, int y) { return x + y; } int add(int x, int y) { return x + y; }
Then: Then:
.. code:: c++ .. code-block:: c++
void f() { void f() {
int x = 2; int x = 2;
@ -25,7 +25,7 @@ Then:
is replaced by: is replaced by:
.. code:: c++ .. code-block:: c++
void f() { void f() {
int x = 2; int x = 2;
@ -35,4 +35,3 @@ is replaced by:
``std::bind`` can be hard to read and can result in larger object files and ``std::bind`` can be hard to read and can result in larger object files and
binaries due to type information that will not be produced by equivalent binaries due to type information that will not be produced by equivalent
lambdas. lambdas.

View File

@ -3,11 +3,11 @@
modernize-use-using modernize-use-using
=================== ===================
Use C++11's ``using`` instead of ``typedef``. The check converts the usage of ``typedef`` with ``using`` keyword.
Before: Before:
.. code:: c++ .. code-block:: c++
typedef int variable; typedef int variable;
@ -16,7 +16,7 @@ Before:
After: After:
.. code:: c++ .. code-block:: c++
using variable = int; using variable = int;

View File

@ -5,18 +5,17 @@ performance-implicit-cast-in-loop
This warning appears in a range-based loop with a loop variable of const ref This warning appears in a range-based loop with a loop variable of const ref
type where the type of the variable does not match the one returned by the type where the type of the variable does not match the one returned by the
iterator. iterator. This means that an implicit cast has been added, which can for example
This means that an implicit cast has been added, which can for example result in result in expensive deep copies.
expensive deep copies.
Example: Example:
.. code:: c++ .. code-block:: c++
map<int, vector<string>> my_map; map<int, vector<string>> my_map;
for (const pair<int, vector<string>>& p : my_map) {} for (const pair<int, vector<string>>& p : my_map) {}
// The iterator type is in fact pair<const int, vector<string>>, which means // The iterator type is in fact pair<const int, vector<string>>, which means
// that the compiler added a cast, resulting in a copy of the vectors. // that the compiler added a cast, resulting in a copy of the vectors.
The easiest solution is usually to use ``const auto&`` instead of writing the type The easiest solution is usually to use ``const auto&`` instead of writing the type
manually. manually.

View File

@ -3,16 +3,18 @@
performance-inefficient-string-concatenation performance-inefficient-string-concatenation
============================================ ============================================
This check warns about the performance overhead arising from concatenating strings using the ``operator+``, for instance: This check warns about the performance overhead arising from concatenating
strings using the ``operator+``, for instance:
.. code:: c++ .. code-block:: c++
std::string a("Foo"), b("Bar"); std::string a("Foo"), b("Bar");
a = a + b; a = a + b;
Instead of this structure you should use ``operator+=`` or ``std::string``'s (``std::basic_string``) class member function ``append()``. For instance: Instead of this structure you should use ``operator+=`` or ``std::string``'s
(``std::basic_string``) class member function ``append()``. For instance:
.. code:: c++ .. code-block:: c++
std::string a("Foo"), b("Baz"); std::string a("Foo"), b("Baz");
for (int i = 0; i < 20000; ++i) { for (int i = 0; i < 20000; ++i) {
@ -21,7 +23,7 @@ Instead of this structure you should use ``operator+=`` or ``std::string``'s (``
Could be rewritten in a greatly more efficient way like: Could be rewritten in a greatly more efficient way like:
.. code:: c++ .. code-block:: c++
std::string a("Foo"), b("Baz"); std::string a("Foo"), b("Baz");
for (int i = 0; i < 20000; ++i) { for (int i = 0; i < 20000; ++i) {
@ -30,7 +32,7 @@ Could be rewritten in a greatly more efficient way like:
And this can be rewritten too: And this can be rewritten too:
.. code:: c++ .. code-block:: c++
void f(const std::string&) {} void f(const std::string&) {}
std::string a("Foo"), b("Baz"); std::string a("Foo"), b("Baz");
@ -40,7 +42,7 @@ And this can be rewritten too:
In a slightly more efficient way like: In a slightly more efficient way like:
.. code:: c++ .. code-block:: c++
void f(const std::string&) {} void f(const std::string&) {}
std::string a("Foo"), b("Baz"); std::string a("Foo"), b("Baz");

View File

@ -3,15 +3,15 @@
readability-avoid-const-params-in-decls readability-avoid-const-params-in-decls
======================================= =======================================
Checks whether a function declaration has parameters that are top level const. Checks whether a function declaration has parameters that are top level
``const``.
`const` values in declarations do not affect the signature of a function, so ``const`` values in declarations do not affect the signature of a function, so
they should not be put there. For example: they should not be put there.
Examples: Examples:
.. code:: c++ .. code-block:: c++
void f(const string); // Bad: const is top level. void f(const string); // Bad: const is top level.
void f(const string&); // Good: const is not top level. void f(const string&); // Good: const is not top level.

View File

@ -6,7 +6,7 @@ readability-deleted-default
Checks that constructors and assignment operators marked as ``= default`` are Checks that constructors and assignment operators marked as ``= default`` are
not actually deleted by the compiler. not actually deleted by the compiler.
.. code:: c++ .. code-block:: c++
class Example { class Example {
public: public:
@ -16,7 +16,7 @@ not actually deleted by the compiler.
Example(const Example& Other) = default; Example(const Example& Other) = default;
// This operator is deleted because I cannot be assigned (it is const). // This operator is deleted because I cannot be assigned (it is const).
Example& operator=(const Example& Other) = default; Example& operator=(const Example& Other) = default;
private: private:
const int I; const int I;
}; };

View File

@ -9,12 +9,13 @@ or in some cases, point to potential bugs which remain unnoticed due to implicit
conversions. conversions.
The following is a real-world example of bug which was hiding behind implicit The following is a real-world example of bug which was hiding behind implicit
bool cast: ``bool`` cast:
.. code:: c++ .. code-block:: c++
class Foo { class Foo {
int m_foo; int m_foo;
public: public:
void setFoo(bool foo) { m_foo = foo; } // warning: implicit cast bool -> int void setFoo(bool foo) { m_foo = foo; } // warning: implicit cast bool -> int
int getFoo() { return m_foo; } int getFoo() { return m_foo; }
@ -29,10 +30,11 @@ changed from ``bool`` to ``int``. The programmer forgot to change all
occurrences of ``bool``, and the remaining code is no longer correct, yet it occurrences of ``bool``, and the remaining code is no longer correct, yet it
still compiles without any visible warnings. still compiles without any visible warnings.
In addition to issuing warnings, FixIt hints are provided to help solve In addition to issuing warnings, fix-it hints are provided to help solve the
the reported issues. This can be used for improving readability of code, for example: reported issues. This can be used for improving readability of code, for
example:
.. code:: c++ .. code-block:: c++
void conversionsToBool() { void conversionsToBool() {
float floating; float floating;
@ -63,37 +65,54 @@ the reported issues. This can be used for improving readability of code, for exa
} }
In general, the following cast types are checked: In general, the following cast types are checked:
- integer expression/literal to boolean,
- floating expression/literal to boolean,
- pointer/pointer to member/``nullptr``/``NULL`` to boolean,
- boolean expression/literal to integer,
- boolean expression/literal to floating.
The rules for generating FixIt hints are: - integer expression/literal to boolean,
- in case of casts from other built-in type to bool, an explicit comparison
is proposed to make it clear what exaclty is being compared:
- ``bool boolean = floating;`` is changed to ``bool boolean = floating == 0.0f;``, - floating expression/literal to boolean,
- for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``, ``0.0``, ``nullptr``),
- in case of negated expressions cast to bool, the proposed replacement with
comparison is simplified:
- ``if (!pointer)`` is changed to ``if (pointer == nullptr)``, - pointer/pointer to member/``nullptr``/``NULL`` to boolean,
- in case of casts from bool to other built-in types, an explicit ``static_cast``
is proposed to make it clear that a cast is taking place:
- ``int integer = boolean;`` is changed to ``int integer = static_cast<int>(boolean);``, - boolean expression/literal to integer,
- if the cast is performed on type literals, an equivalent literal is proposed,
according to what type is actually expected, for example:
- ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``, - boolean expression/literal to floating.
- ``functionTakingInt(true);`` is changed to ``functionTakingInt(1);``,
- for other types, appropriate literals are used (``false``, ``true``, ``0``, ``1``, ``0u``, ``1u``, The rules for generating fix-it hints are:
``0.0f``, ``1.0f``, ``0.0``, ``1.0f``).
- in case of casts from other built-in type to bool, an explicit comparison
is proposed to make it clear what exaclty is being compared:
- ``bool boolean = floating;`` is changed to
``bool boolean = floating == 0.0f;``,
- for other types, appropriate literals are used (``0``, ``0u``, ``0.0f``,
``0.0``, ``nullptr``),
- in case of negated expressions cast to bool, the proposed replacement with
comparison is simplified:
- ``if (!pointer)`` is changed to ``if (pointer == nullptr)``,
- in case of casts from bool to other built-in types, an explicit ``static_cast``
is proposed to make it clear that a cast is taking place:
- ``int integer = boolean;`` is changed to
``int integer = static_cast<int>(boolean);``,
- if the cast is performed on type literals, an equivalent literal is proposed,
according to what type is actually expected, for example:
- ``functionTakingBool(0);`` is changed to ``functionTakingBool(false);``,
- ``functionTakingInt(true);`` is changed to ``functionTakingInt(1);``,
- for other types, appropriate literals are used (``false``, ``true``, ``0``,
``1``, ``0u``, ``1u``, ``0.0f``, ``1.0f``, ``0.0``, ``1.0f``).
Some additional accommodations are made for pre-C++11 dialects: Some additional accommodations are made for pre-C++11 dialects:
- ``false`` literal cast to pointer is detected,
- instead of ``nullptr`` literal, ``0`` is proposed as replacement. - ``false`` literal cast to pointer is detected,
- instead of ``nullptr`` literal, ``0`` is proposed as replacement.
Occurrences of implicit casts inside macros and template instantiations are Occurrences of implicit casts inside macros and template instantiations are
deliberately ignored, as it is not clear how to deal with such cases. deliberately ignored, as it is not clear how to deal with such cases.

View File

@ -3,12 +3,11 @@
readability-inconsistent-declaration-parameter-name readability-inconsistent-declaration-parameter-name
=================================================== ===================================================
Find function declarations which differ in parameter names. Find function declarations which differ in parameter names.
Example: Example:
.. code:: c++ .. code-block:: c++
// in foo.hpp: // in foo.hpp:
void foo(int a, int b, int c); void foo(int a, int b, int c);
@ -25,20 +24,20 @@ definition always in sync.
Unnamed parameters are allowed and are not taken into account when comparing Unnamed parameters are allowed and are not taken into account when comparing
function declarations, for example: function declarations, for example:
.. code:: c++ .. code-block:: c++
void foo(int a); void foo(int a);
void foo(int); // no warning void foo(int); // no warning
To help with refactoring, in some cases FixIt hints are generated to align To help with refactoring, in some cases fix-it hints are generated to align
parameter names to a single naming convention. This works with the assumption parameter names to a single naming convention. This works with the assumption
that the function definition is the most up-to-date version, as it directly that the function definition is the most up-to-date version, as it directly
references parameter names in its body. Example: references parameter names in its body. Example:
.. code:: c++ .. code-block:: c++
void foo(int a); // warning and FixIt hint (replace "a" to "b") void foo(int a); // warning and fix-it hint (replace "a" to "b")
int foo(int b) { return b + 2; } // definition with use of "b" int foo(int b) { return b + 2; } // definition with use of "b"
In the case of multiple redeclarations or function template specializations, In the case of multiple redeclarations or function template specializations,
a warning is issued for every redeclaration or specialization inconsistent with a warning is issued for every redeclaration or specialization inconsistent with

View File

@ -3,12 +3,11 @@
readability-redundant-string-init readability-redundant-string-init
================================= =================================
Finds unnecessary string initializations. Finds unnecessary string initializations.
Examples: Examples:
.. code:: c++ .. code-block:: c++
// Initializing string with empty string literal is unnecessary. // Initializing string with empty string literal is unnecessary.
std::string a = ""; std::string a = "";

View File

@ -8,7 +8,7 @@ Finds static function and variable definitions in anonymous namespace.
In this case, ``static`` is redundant, because anonymous namespace limits the In this case, ``static`` is redundant, because anonymous namespace limits the
visibility of definitions to a single translation unit. visibility of definitions to a single translation unit.
.. code:: c++ .. code-block:: c++
namespace { namespace {
static int a = 1; // Warning. static int a = 1; // Warning.