Sometimes in the AST we can have an ArraySubscriptExpr,
where the index is an ArrayInitIndexExpr.
ArrayInitIndexExpr is not a constant, so
ProBoundsConstantArrayIndexCheck reports a warning when
it sees such expression. This expression can only be
implicitly generated, and always appears inside an
ArrayInitLoopExpr, so we shouldn't report a warning.
Differential Revision: https://reviews.llvm.org/D132654
Lambdas are implemented as regular classes internally,
and the captured variables end up as members there.
Do not diagnose those - the check should cover only
regular classes and structs.
Differential Revision: https://reviews.llvm.org/D131780
Flags uses of const-qualified and reference data members in structs.
Implements rule C.12 of C++ Core Guidelines.
Differential Revision: https://reviews.llvm.org/D126880
In case of a variable with a built-in boolean type, `false` is a better fit to default-initialize it.
Reviewed By: njames93
Differential Revision: https://reviews.llvm.org/D129420
Check llvm::Optional before dereferencing it.
Compute VirtualEndLoc differently to avoid an assertion failure
in clang::SourceManager::getFileIDLoaded:
Assertion `0 && "Invalid SLocOffset or bad function choice"' failed
The `cppcoreguidelines-virtual-class-destructor` supposed to enforce
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-non-virtual
Quote:
> A **base** class destructor should be either public and virtual, or
> protected and non-virtual
[emphasis mine]
However, this check still rules the following case:
class MostDerived final : public Base {
public:
MostDerived() = default;
~MostDerived() = default;
void func() final;
};
Even though `MostDerived` class is marked `final`, thus it should not be
considered as a **base** class. Consequently, the rule is satisfied, yet
the check still flags this code.
In this patch, I'm proposing to ignore `final` classes since they cannot
be //base// classes.
Reviewed By: whisperity
Differential Revision: https://reviews.llvm.org/D126891
- Rename doc files to subdirs by module
- Update release notes and check list to use subdirs
- Update add_new_check.py to handle doc subdirs
Differential Revision: https://reviews.llvm.org/D126495
There's many instances in clang tidy checks where owning strings are used when we already have a stable string from the options, so using a StringRef makes much more sense.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D124341
Adds a flag to `ClangTidyContext` that is used to indicate to checks that fixes will only be applied one at a time.
This is to indicate to checks that each fix emitted should not depend on any other fixes emitted across the translation unit.
I've currently implemented the `IncludeInserter`, `LoopConvertCheck` and `PreferMemberInitializerCheck` to use these support these modes.
Reasoning behind this is in use cases like `clangd` it's only possible to apply one fix at a time.
For include inserter checks, the include is only added once for the first diagnostic that requires it, this will result in subsequent fixes not having the included needed.
A similar issue is seen in the `PreferMemberInitializerCheck` where the `:` will only be added for the first member that needs fixing.
Fixes emitted in `StandaloneDiagsMode` will likely result in malformed code if they are applied all together, conversely fixes currently emitted may result in malformed code if they are applied one at a time.
For this reason invoking `clang-tidy` from the binary will always with `StandaloneDiagsMode` disabled, However using it as a library its possible to select the mode you wish to use, `clangd` always selects `StandaloneDiagsMode`.
This is an example of the current behaviour failing
```lang=c++
struct Foo {
int A, B;
Foo(int D, int E) {
A = D;
B = E; // Fix Here
}
};
```
Incorrectly transformed to:
```lang=c++
struct Foo {
int A, B;
Foo(int D, int E), B(E) {
A = D;
// Fix Here
}
};
```
In `StandaloneDiagsMode`, it gets transformed to:
```lang=c++
struct Foo {
int A, B;
Foo(int D, int E) : B(E) {
A = D;
// Fix Here
}
};
```
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D97121
Currently the fix hint is hardcoded to gsl::at(). This poses
a problem for people who, for a number of reasons, don't want
or cannot use the GSL library (introducing a new third-party
dependency into a project is not a minor task).
In these situations, the fix hint does more harm than good
as it creates confusion as to what the fix should be. People
can even misinterpret the fix "gsl::at" as e.g. "std::array::at",
which can lead to even more trouble (e.g. when having guidelines
that disallow exceptions).
Furthermore, this is not a requirement from the C++ Core Guidelines.
simply that array indexing needs to be safe. Each project should
be able to decide upon a strategy for safe indexing.
The fix-it is kept for people who want to use the GSL library.
Differential Revision: https://reviews.llvm.org/D117857
Previously, any macro that didn't look like a varargs macro
or a function style macro was reported with a warning that
it should be replaced with a constexpr const declaration.
This is only reasonable when the macro body contains constants
and not expansions like ",", "[[noreturn]]", "__declspec(xxx)",
etc.
So instead of always issuing a warning about every macro that
doesn't look like a varargs or function style macro, examine the
tokens in the macro and only warn about the macro if it contains
only comment and constant tokens.
Differential Revision: https://reviews.llvm.org/D116386Fixes#39945
The cppcoreguidelines-pro-bounds-array-to-pointer-decay check currently
accepts:
const char *b = i ? "foo" : "foobar";
but not
const char *a = i ? "foo" : "bar";
This is because the AST is slightly different in the latter case (see
https://godbolt.org/z/MkHVvs).
This eliminates the inconsistency by making it accept the latter form
as well.
Fixes https://github.com/llvm/llvm-project/issues/31155.
Currently, it's inconsistent that warnings are disabled if they
come from system headers, unless they come from macros.
Typically a user cannot act upon these warnings coming from
system macros, so clang-tidy should ignore them unless the
user specifically requests warnings from system headers
via the corresponding configuration.
This change broke the ProTypeVarargCheck check, because it
was checking for the usage of va_arg indirectly, expanding it
(it's a system macro) to detect the usage of __builtin_va_arg.
The check has been fixed by checking directly what the rule
is about: "do not use va_arg", by adding a PP callback that
checks if any macro with name "va_arg" is expanded. The old
AST matcher is still kept for compatibility with Windows.
Add unit test that ensures warnings from macros are disabled
when not using the -system-headers flag. Document the change
in the Release Notes.
Differential Revision: https://reviews.llvm.org/D116378
This change adds an option to disable warnings from the
cppcoreguidelines-narrowing-conversions check on integer to floating-
point conversions which may be narrowing.
An example of a case where this might be useful:
```
std::vector<double> v = {1, 2, 3, 4};
double mean = std::accumulate(v.cbegin(), v.cend(), 0.0) / v.size();
```
The conversion from std::size_t to double is technically narrowing on
64-bit systems, but v almost certainly does not have enough elements
for this to be a problem.
This option would allow the cppcoreguidelines-narrowing-conversions
check to be enabled on codebases which might otherwise turn it off
because of cases like the above.
Bitfields are special. Due to integral promotion [conv.prom/5] bitfield
member access expressions are frequently wrapped by an implicit cast to
`int` if that type can represent all the values of the bitfield.
Consider these examples:
struct SmallBitfield { unsigned int id : 4; };
x.id & 1; (case-1)
x.id & 1u; (case-2)
x.id << 1u; (case-3)
(unsigned)x.id << 1; (case-4)
Due to the promotion rules, we would get a warning for case-1. It's
debatable how useful this is, but the user at least has a convenient way
of //fixing// it by adding the `u` unsigned-suffix to the literal as
demonstrated by case-2. However, this won't work for shift operators like
the one in case-3. In case of a normal binary operator, both operands
contribute to the result type. However, the type of the shift expression is
the promoted type of the left operand. One could still suppress this
superfluous warning by explicitly casting the bitfield member access as
case-4 demonstrates, but why? The compiler already knew that the value from
the member access should safely fit into an `int`, why do we have this
warning in the first place? So, hereby we suppress this specific scenario,
when a bitfield's value is implicitly cast to int (likely due to integral
promotion).
Note that the bitshift operation might invoke unspecified/undefined
behavior, but that's another topic, this checker is about detecting
conversion-related defects.
Example AST for `x.id << 1`:
BinaryOperator 'int' '<<'
|-ImplicitCastExpr 'int' <IntegralCast>
| `-ImplicitCastExpr 'unsigned int' <LValueToRValue>
| `-MemberExpr 'unsigned int' lvalue bitfield .id
| `-DeclRefExpr 'SmallBitfield' lvalue ParmVar 'x' 'SmallBitfield'
`-IntegerLiteral 'int' 1
Reviewed By: courbet
Differential Revision: https://reviews.llvm.org/D114105
The `cppcoreguidelines-virtual-base-class-destructor` checker crashed on
this example:
#define DECLARE(CLASS) \
class CLASS { \
protected: \
virtual ~CLASS(); \
}
DECLARE(Foo); // no-crash
The checker will hit the following assertion:
clang-tidy: llvm/include/llvm/ADT/Optional.h:196: T &llvm::optional_detail::OptionalStorage<clang::Token, true>::getValue() & [T = clang::Token]: Assertion `hasVal' failed."
It turns out, `Lexer::findNextToken()` returned `llvm::None` within the
`getVirtualKeywordRange()` function when the `VirtualEndLoc`
SourceLocation represents a macro expansion.
To prevent this from happening, I decided to propagate the `llvm::None`
further up and only create the removal of `virtual` if the
`getVirtualKeywordRange()` succeeds.
I considered an alternative fix for this issue:
I could have checked the `Destructor.getLocation().isMacroID()` before
doing any Fixit calculation inside the `check()` function.
In contrast to this approach my patch will preserve the diagnostics and
drop the fixits only if it would have crashed.
Reviewed By: whisperity
Differential Revision: https://reviews.llvm.org/D113558
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.
As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith, #libc, ldionne
Differential Revision: https://reviews.llvm.org/D110216
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.
As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D110216
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.
As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D110216
Run clang-tidy on all source files under `clang-tools-extra/clang-tidy`
with `-header-filter=clang-tidy.*` and make suggested corrections.
Differential Revision: https://reviews.llvm.org/D112864
Incorrectly triggers for template classes that inherit
from a base class that has virtual destructor.
Any class inheriting from a base that has a virtual destructor
will have their destructor also virtual, as per the Standard:
https://timsong-cpp.github.io/cppwp/n4140/class.dtor#9
> If a class has a base class with a virtual destructor,
> its destructor (whether user- or implicitly-declared) is virtual.
Added unit tests to prevent regression.
Fixes bug https://bugs.llvm.org/show_bug.cgi?id=51912
Differential Revision: https://reviews.llvm.org/D110614
This requirement was introduced in the C++ Core guidelines in 2016:
1894380d0a
Then clang-tidy got updated to comply with the rule.
However in 2019 this decision was reverted:
5fdfb20b76
Therefore we need to apply the correct configuration to
clang-tidy again.
This also makes this cppcoreguidelines check consistent
with the other 2 alias checks: hicpp-use-override and
modernize-use-override.
Additionally, add another RUN line to the unit test,
to make sure cppcoreguidelines-explicit-virtual-functions
is tested.
At most one variant member of a union may have a default member
initializer. The case of anonymous records with multiple levels of
nesting like the following also needs to meet this rule. The original
logic is to horizontally obtain all the member variables in a record
that need to be initialized and then filter to the variables that need
to be fixed. Obviously, it is impossible to correctly initialize the
desired variables according to the nesting relationship.
See Example 3 in class.union
union U {
U() {}
int x; // int x{};
union {
int k; // int k{}; <== wrong fix
};
union {
int z; // int z{}; <== wrong fix
int y;
};
};
Finds base classes and structs whose destructor is neither public and
virtual nor protected and non-virtual.
A base class's destructor should be specified in one of these ways to
prevent undefined behaviour.
Fixes are available for user-declared and implicit destructors that are
either public and non-virtual or protected and virtual.
This check implements C.35 [1] from the CppCoreGuidelines.
Reviewed By: aaron.ballman, njames93
Differential Revision: http://reviews.llvm.org/D102325
[1]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-dtor-virtual
The overload of the constructor will repeatedly fix the member variables that need to be initialized.
Removed the duplicate '{}'.
```
struct A {
A() {}
A(int) {}
int _var; // int _var{}{}; <-- wrong fix
};
```
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D107641
FixIt, and add support for initialization check of scoped enum
In C++, the enumeration is never Integer, and the enumeration condition judgment is added to avoid compiling errors when it is initialized to an integer.
Add support for initialization check of scope enum.
As the following case show, clang-tidy will give a wrong automatic fix:
enum Color {Red, Green, Blue};
enum class Gender {Male, Female};
void func() {
Color color; // Color color = 0; <--- fix bug
Gender gender; // <--- no warning
}
Reviewd By: aaron.ballman, whisperity
Differential Revision: http://reviews.llvm.org/D106431
<string> is currently the highest impact header in a clang+llvm build:
https://commondatastorage.googleapis.com/chromium-browser-clang/llvm-include-analysis.html
One of the most common places this is being included is the APInt.h header, which needs it for an old toString() implementation that returns std::string - an inefficient method compared to the SmallString versions that it actually wraps.
This patch replaces these APInt/APSInt methods with a pair of llvm::toString() helpers inside StringExtras.h, adjusts users accordingly and removes the <string> from APInt.h - I was hoping that more of these users could be converted to use the SmallString methods, but it appears that most end up creating a std::string anyhow. I avoided trying to use the raw_ostream << operators as well as I didn't want to lose having the integer radix explicit in the code.
Differential Revision: https://reviews.llvm.org/D103888
mixed integer and floating point types with WarnOnEquivalentBitWidth=0.
Also standardize control flow of handleX conversion functions to make it easier to be consistent.
Patch by Stephen Concannon!
Differential Revision: https://reviews.llvm.org/D103894
Within clang-tidy's NarrowingConversionsCheck.
* Allow opt-out of some common occurring patterns, such as:
- Implicit casts between types of equivalent bit widths.
- Implicit casts occurring from the return of a ::size() method.
- Implicit casts on size_type and difference_type.
* Allow opt-in of errors within template instantiations.
This will help projects adopt these guidelines iteratively.
Developed in conjunction with Yitzhak Mandelbaum (ymandel).
Patch by Stephen Concannon!
Differential Revision: https://reviews.llvm.org/D99543
Change instances where options which are boolean are assigned the value 1|0 to use true|false instead.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D101721
This commit fixes cppcoreguidelines-pro-type-vararg false positives on
'char *' variables.
The incorrect warnings generated by clang-tidy can be illustrated with
the following minimal example:
```
goid foo(char* in) {
char *tmp = in;
}
```
The problem is that __builtin_ms_va_list desugared as 'char *', which
leads to false positives.
Fixes bugzilla issue 48042.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D101259