58 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "DynamicStaticInitializersCheck.h"10#include "../utils/FileExtensionsUtils.h"11#include "clang/AST/ASTContext.h"12#include "clang/ASTMatchers/ASTMatchFinder.h"13 14using namespace clang::ast_matchers;15 16namespace clang::tidy::bugprone {17 18namespace {19 20AST_MATCHER(clang::VarDecl, hasConstantDeclaration) {21 const Expr *Init = Node.getInit();22 if (Init && !Init->isValueDependent()) {23 if (Node.isConstexpr())24 return true;25 return Node.evaluateValue();26 }27 return false;28}29 30} // namespace31 32DynamicStaticInitializersCheck::DynamicStaticInitializersCheck(33 StringRef Name, ClangTidyContext *Context)34 : ClangTidyCheck(Name, Context),35 HeaderFileExtensions(Context->getHeaderFileExtensions()) {}36 37void DynamicStaticInitializersCheck::registerMatchers(MatchFinder *Finder) {38 Finder->addMatcher(39 varDecl(hasGlobalStorage(), unless(hasConstantDeclaration())).bind("var"),40 this);41}42 43void DynamicStaticInitializersCheck::check(44 const MatchFinder::MatchResult &Result) {45 const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var");46 const SourceLocation Loc = Var->getLocation();47 if (!Loc.isValid() || !utils::isPresumedLocInHeaderFile(48 Loc, *Result.SourceManager, HeaderFileExtensions))49 return;50 // If the initializer is a constant expression, then the compiler51 // doesn't have to dynamically initialize it.52 diag(Loc,53 "static variable %0 may be dynamically initialized in this header file")54 << Var;55}56 57} // namespace clang::tidy::bugprone58