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 IncludeInserter(Options.getLocalOrGlobal(
"IncludeStyle",
30 utils::IncludeSorter::IS_LLVM),
31 areDiagsSelfContained()),
32 MathHeader(Options.get(
"MathHeader",
"<math.h>")) {}
40 std::string BadDecl =
"badDecl";
42 varDecl(unless(hasInitializer(anything())), unless(isInstantiated()),
43 isLocalVarDecl(), unless(isStaticLocal()), isDefinition(),
44 unless(hasParent(cxxCatchStmt())),
45 optionally(hasParent(declStmt(hasParent(
46 cxxForRangeStmt(hasLoopVariable(varDecl().bind(BadDecl))))))),
47 unless(equalsBoundNode(BadDecl)))
54 Preprocessor *ModuleExpanderPP) {
59 const auto *MatchedDecl = Result.Nodes.getNodeAs<VarDecl>(
"vardecl");
60 const ASTContext &Context = *Result.Context;
61 const SourceManager &Source = Context.getSourceManager();
78 if (MatchedDecl->getEndLoc().isMacroID())
81 QualType TypePtr = MatchedDecl->getType();
82 llvm::Optional<const char *> InitializationString = llvm::None;
83 bool AddMathInclude =
false;
85 if (TypePtr->isEnumeralType())
86 InitializationString =
nullptr;
87 else if (TypePtr->isIntegerType())
88 InitializationString =
" = 0";
89 else if (TypePtr->isFloatingType()) {
90 InitializationString =
" = NAN";
91 AddMathInclude =
true;
92 }
else if (TypePtr->isAnyPointerType()) {
94 InitializationString =
" = nullptr";
96 InitializationString =
" = NULL";
99 if (InitializationString) {
101 diag(MatchedDecl->getLocation(),
"variable %0 is not initialized")
103 if (*InitializationString !=
nullptr)
105 MatchedDecl->getLocation().getLocWithOffset(
106 MatchedDecl->getName().size()),
107 *InitializationString);
108 if (AddMathInclude) {
110 Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader);