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