55 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 "InterfacesGlobalInitCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11 12using namespace clang::ast_matchers;13 14namespace clang::tidy::cppcoreguidelines {15 16void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {17 const auto GlobalVarDecl =18 varDecl(hasGlobalStorage(),19 hasDeclContext(anyOf(translationUnitDecl(), // Global scope.20 namespaceDecl(), // Namespace scope.21 recordDecl())), // Class scope.22 unless(isConstexpr()), unless(isConstinit()));23 24 const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(25 varDecl(GlobalVarDecl, unless(isDefinition())).bind("referencee")));26 27 Finder->addMatcher(28 traverse(TK_AsIs, varDecl(GlobalVarDecl, isDefinition(),29 hasInitializer(expr(hasDescendant(30 ReferencesUndefinedGlobalVar))))31 .bind("var")),32 this);33}34 35void InterfacesGlobalInitCheck::check(const MatchFinder::MatchResult &Result) {36 const auto *const Var = Result.Nodes.getNodeAs<VarDecl>("var");37 // For now assume that people who write macros know what they're doing.38 if (Var->getLocation().isMacroID())39 return;40 const auto *const Referencee = Result.Nodes.getNodeAs<VarDecl>("referencee");41 // If the variable has been defined, we're good.42 const auto *const ReferenceeDef = Referencee->getDefinition();43 if (ReferenceeDef != nullptr &&44 Result.SourceManager->isBeforeInTranslationUnit(45 ReferenceeDef->getLocation(), Var->getLocation())) {46 return;47 }48 diag(Var->getLocation(),49 "initializing non-local variable with non-const expression depending on "50 "uninitialized non-local variable %0")51 << Referencee;52}53 54} // namespace clang::tidy::cppcoreguidelines55