forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
clang-tidy: add check for non-trivial thread_local vars
Do not allow thread_local vars with non-trivial destructors
- Loading branch information
Showing
5 changed files
with
79 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
contrib/devtools/bitcoin-tidy/example_nontrivial-threadlocal.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#include <string> | ||
thread_local std::string foo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright (c) 2023 Bitcoin Developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include "nontrivial-threadlocal.h" | ||
|
||
#include <clang/AST/ASTContext.h> | ||
#include <clang/ASTMatchers/ASTMatchFinder.h> | ||
|
||
|
||
// Copied from clang-tidy's UnusedRaiiCheck | ||
namespace { | ||
AST_MATCHER(clang::CXXRecordDecl, hasNonTrivialDestructor) { | ||
// TODO: If the dtor is there but empty we don't want to warn either. | ||
return Node.hasDefinition() && Node.hasNonTrivialDestructor(); | ||
} | ||
} // namespace | ||
|
||
namespace bitcoin { | ||
|
||
void NonTrivialThreadLocal::registerMatchers(clang::ast_matchers::MatchFinder* finder) | ||
{ | ||
using namespace clang::ast_matchers; | ||
|
||
/* | ||
thread_local std::string foo; | ||
*/ | ||
|
||
finder->addMatcher( | ||
varDecl( | ||
hasThreadStorageDuration(), | ||
hasType(hasCanonicalType(recordType(hasDeclaration(cxxRecordDecl(hasNonTrivialDestructor()))))) | ||
).bind("nontrivial_threadlocal"), | ||
this); | ||
} | ||
|
||
void NonTrivialThreadLocal::check(const clang::ast_matchers::MatchFinder::MatchResult& Result) | ||
{ | ||
if (const clang::VarDecl* var = Result.Nodes.getNodeAs<clang::VarDecl>("nontrivial_threadlocal")) { | ||
const auto user_diag = diag(var->getBeginLoc(), "Variable with non-trivial destructor cannot be thread_local."); | ||
} | ||
} | ||
|
||
} // namespace bitcoin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) 2023 Bitcoin Developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#ifndef NONTRIVIAL_THREADLOCAL_CHECK_H | ||
#define NONTRIVIAL_THREADLOCAL_CHECK_H | ||
|
||
#include <clang-tidy/ClangTidyCheck.h> | ||
|
||
namespace bitcoin { | ||
|
||
// Warn about any thread_local variable with a non-trivial destructor. | ||
class NonTrivialThreadLocal final : public clang::tidy::ClangTidyCheck | ||
{ | ||
public: | ||
NonTrivialThreadLocal(clang::StringRef Name, clang::tidy::ClangTidyContext* Context) | ||
: clang::tidy::ClangTidyCheck(Name, Context) {} | ||
|
||
bool isLanguageVersionSupported(const clang::LangOptions& LangOpts) const override | ||
{ | ||
return LangOpts.CPlusPlus; | ||
} | ||
void registerMatchers(clang::ast_matchers::MatchFinder* Finder) override; | ||
void check(const clang::ast_matchers::MatchFinder::MatchResult& Result) override; | ||
}; | ||
|
||
} // namespace bitcoin | ||
|
||
#endif // NONTRIVIAL_THREADLOCAL_CHECK_H |