Skip to content

Commit 72b6a57

Browse files
authored
[clang-tidy] fix false positives when using name-independent variables after C++26 for bugprone-unused-local-non-trivial-variable (#121783)
Fixed: #121731 According to https://eel.is/c++draft/basic.scope.scope#5, name independent declaration should not be warned as unused
1 parent 51d7605 commit 72b6a57

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

clang-tools-extra/clang-tidy/bugprone/UnusedLocalNonTrivialVariableCheck.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ static constexpr StringRef DefaultIncludeTypeRegex =
2929

3030
AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); }
3131
AST_MATCHER(VarDecl, isReferenced) { return Node.isReferenced(); }
32+
AST_MATCHER_P(VarDecl, explicitMarkUnused, LangOptions, LangOpts) {
33+
// Implementations should not emit a warning that a name-independent
34+
// declaration is used or unused.
35+
return Node.hasAttr<UnusedAttr>() ||
36+
(LangOpts.CPlusPlus26 && Node.isPlaceholderVar(LangOpts));
37+
}
3238
AST_MATCHER(Type, isReferenceType) { return Node.isReferenceType(); }
3339
AST_MATCHER(QualType, isTrivial) {
3440
return Node.isTrivialType(Finder->getASTContext()) ||
@@ -60,7 +66,7 @@ void UnusedLocalNonTrivialVariableCheck::registerMatchers(MatchFinder *Finder) {
6066
varDecl(isLocalVarDecl(), unless(isReferenced()),
6167
unless(isExceptionVariable()), hasLocalStorage(), isDefinition(),
6268
unless(hasType(isReferenceType())), unless(hasType(isTrivial())),
63-
unless(hasAttr(attr::Kind::Unused)),
69+
unless(explicitMarkUnused(getLangOpts())),
6470
hasType(hasUnqualifiedDesugaredType(
6571
anyOf(recordType(hasDeclaration(namedDecl(
6672
matchesAnyListedName(IncludeTypes),

clang-tools-extra/docs/ReleaseNotes.rst

+4
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ Changes in existing checks
241241
<clang-tidy/checks/bugprone/unsafe-functions>` check to allow specifying
242242
additional functions to match.
243243

244+
- Improved :doc:`bugprone-unused-local-non-trivial-variable
245+
<clang-tidy/checks/bugprone/unused-local-non-trivial-variable>` check to avoid
246+
false positives when using name-independent variables after C++26.
247+
244248
- Improved :doc:`bugprone-use-after-move
245249
<clang-tidy/checks/bugprone/use-after-move>` to avoid triggering on
246250
``reset()`` calls on moved-from ``std::optional`` and ``std::any`` objects,

clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-local-non-trivial-variable.rst

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The following types of variables are excluded from this check:
1212
* static or thread local
1313
* structured bindings
1414
* variables with ``[[maybe_unused]]`` attribute
15+
* name-independent variables
1516

1617
This check can be configured to warn on all non-trivial variables by setting
1718
`IncludeTypes` to `.*`, and excluding specific types using `ExcludeTypes`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %check_clang_tidy -std=c++23 -check-suffixes=,CXX23 %s bugprone-unused-local-non-trivial-variable %t -- \
2+
// RUN: -config="{CheckOptions: {bugprone-unused-local-non-trivial-variable.IncludeTypes: '::async::Foo'}}" \
3+
// RUN: --
4+
// RUN: %check_clang_tidy -std=c++26 %s bugprone-unused-local-non-trivial-variable %t -- \
5+
// RUN: -config="{CheckOptions: {bugprone-unused-local-non-trivial-variable.IncludeTypes: '::async::Foo'}}" \
6+
// RUN: --
7+
8+
namespace async {
9+
class Foo {
10+
public:
11+
~Foo();
12+
private:
13+
};
14+
} // namespace async
15+
16+
void check() {
17+
async::Foo C;
18+
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: unused local variable 'C' of type 'async::Foo' [bugprone-unused-local-non-trivial-variable]
19+
async::Foo _;
20+
// CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: unused local variable '_' of type 'async::Foo' [bugprone-unused-local-non-trivial-variable]
21+
}

0 commit comments

Comments
 (0)