11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/PPCallbacks.h"
14 #include "clang/Lex/Preprocessor.h"
20 namespace cppcoreguidelines {
23 AST_MATCHER(VarDecl, isLocalVarDecl) {
return Node.isLocalVarDecl(); }
26 InitVariablesCheck::InitVariablesCheck(StringRef
Name,
29 IncludeStyle(Options.getLocalOrGlobal(
"IncludeStyle",
30 utils::IncludeSorter::IS_LLVM)),
31 MathHeader(Options.get(
"MathHeader",
"math.h")) {}
39 std::string BadDecl =
"badDecl";
41 varDecl(unless(hasInitializer(anything())), unless(isInstantiated()),
42 isLocalVarDecl(), unless(isStaticLocal()), isDefinition(),
43 unless(hasParent(cxxCatchStmt())),
44 optionally(hasParent(declStmt(hasParent(
45 cxxForRangeStmt(hasLoopVariable(varDecl().bind(BadDecl))))))),
46 unless(equalsBoundNode(BadDecl)))
53 Preprocessor *ModuleExpanderPP) {
55 std::make_unique<utils::IncludeInserter>(SM,
getLangOpts(), IncludeStyle);
56 PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
60 const auto *MatchedDecl = Result.Nodes.getNodeAs<VarDecl>(
"vardecl");
61 const ASTContext &Context = *Result.Context;
62 const SourceManager &Source = Context.getSourceManager();
79 if (MatchedDecl->getEndLoc().isMacroID())
82 QualType TypePtr = MatchedDecl->getType();
83 const char *InitializationString =
nullptr;
84 bool AddMathInclude =
false;
86 if (TypePtr->isIntegerType())
87 InitializationString =
" = 0";
88 else if (TypePtr->isFloatingType()) {
89 InitializationString =
" = NAN";
90 AddMathInclude =
true;
91 }
else if (TypePtr->isAnyPointerType()) {
93 InitializationString =
" = nullptr";
95 InitializationString =
" = NULL";
98 if (InitializationString) {
100 diag(MatchedDecl->getLocation(),
"variable %0 is not initialized")
102 << FixItHint::CreateInsertion(
103 MatchedDecl->getLocation().getLocWithOffset(
104 MatchedDecl->getName().size()),
105 InitializationString);
106 if (AddMathInclude) {
107 Diagnostic << IncludeInserter->CreateIncludeInsertion(
108 Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader,
false);