10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
17 namespace cppcoreguidelines {
19 void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
20 const auto GlobalVarDecl =
21 varDecl(hasGlobalStorage(),
22 hasDeclContext(anyOf(translationUnitDecl(),
25 unless(isConstexpr()));
27 const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
28 varDecl(GlobalVarDecl, unless(isDefinition())).bind(
"referencee")));
30 Finder->addMatcher(traverse(ast_type_traits::TK_AsIs,
31 varDecl(GlobalVarDecl, isDefinition(),
32 hasInitializer(expr(hasDescendant(
33 ReferencesUndefinedGlobalVar))))
38 void InterfacesGlobalInitCheck::check(
const MatchFinder::MatchResult &Result) {
39 const auto *
const Var = Result.Nodes.getNodeAs<VarDecl>(
"var");
41 if (Var->getLocation().isMacroID())
43 const auto *
const Referencee = Result.Nodes.getNodeAs<VarDecl>(
"referencee");
45 const auto *
const ReferenceeDef = Referencee->getDefinition();
46 if (ReferenceeDef !=
nullptr &&
47 Result.SourceManager->isBeforeInTranslationUnit(
48 ReferenceeDef->getLocation(), Var->getLocation())) {
51 diag(Var->getLocation(),
52 "initializing non-local variable with non-const expression depending on "
53 "uninitialized non-local variable %0")