nontrivial-threadlocal.cpp raw
1 // Copyright (c) 2023 Bitcoin Developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "nontrivial-threadlocal.h"
6
7 #include <clang/AST/ASTContext.h>
8 #include <clang/ASTMatchers/ASTMatchFinder.h>
9
10
11 // Copied from clang-tidy's UnusedRaiiCheck
12 namespace {
13 AST_MATCHER(clang::CXXRecordDecl, hasNonTrivialDestructor) {
14 // TODO: If the dtor is there but empty we don't want to warn either.
15 return Node.hasDefinition() && Node.hasNonTrivialDestructor();
16 }
17 } // namespace
18
19 namespace bitcoin {
20
21 void NonTrivialThreadLocal::registerMatchers(clang::ast_matchers::MatchFinder* finder)
22 {
23 using namespace clang::ast_matchers;
24
25 /*
26 thread_local std::string foo;
27 */
28
29 finder->addMatcher(
30 varDecl(
31 hasThreadStorageDuration(),
32 hasType(hasCanonicalType(recordType(hasDeclaration(cxxRecordDecl(hasNonTrivialDestructor())))))
33 ).bind("nontrivial_threadlocal"),
34 this);
35 }
36
37 void NonTrivialThreadLocal::check(const clang::ast_matchers::MatchFinder::MatchResult& Result)
38 {
39 if (const clang::VarDecl* var = Result.Nodes.getNodeAs<clang::VarDecl>("nontrivial_threadlocal")) {
40 const auto user_diag = diag(var->getBeginLoc(), "Variable with non-trivial destructor cannot be thread_local.");
41 }
42 }
43
44 } // namespace bitcoin
45