llvm-project
51 строка · 1.8 Кб
1//===--- DynamicStaticInitializersCheck.cpp - clang-tidy ------------------===//
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-exception
6//
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
18AST_MATCHER(clang::VarDecl, hasConstantDeclaration) {19const Expr *Init = Node.getInit();20if (Init && !Init->isValueDependent()) {21if (Node.isConstexpr())22return true;23return Node.evaluateValue();24}25return false;26}
27
28DynamicStaticInitializersCheck::DynamicStaticInitializersCheck(29StringRef Name, ClangTidyContext *Context)30: ClangTidyCheck(Name, Context),31HeaderFileExtensions(Context->getHeaderFileExtensions()) {}32
33void DynamicStaticInitializersCheck::registerMatchers(MatchFinder *Finder) {34Finder->addMatcher(35varDecl(hasGlobalStorage(), unless(hasConstantDeclaration())).bind("var"),36this);37}
38
39void DynamicStaticInitializersCheck::check(const MatchFinder::MatchResult &Result) {40const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var");41SourceLocation Loc = Var->getLocation();42if (!Loc.isValid() || !utils::isPresumedLocInHeaderFile(Loc, *Result.SourceManager,43HeaderFileExtensions))44return;45// If the initializer is a constant expression, then the compiler46// doesn't have to dynamically initialize it.47diag(Loc, "static variable %0 may be dynamically initialized in this header file")48<< Var;49}
50
51} // namespace clang::tidy::bugprone52