45 const std::string BadDecl =
"badDecl";
47 varDecl(unless(hasInitializer(anything())), unless(isInstantiated()),
48 isLocalVarDecl(), unless(isStaticLocal()), isDefinition(),
49 unless(hasParent(cxxCatchStmt())),
50 unless(hasParent(declStmt(hasParent(isObjCForCollectionStmt())))),
51 optionally(hasParent(declStmt(hasParent(
52 cxxForRangeStmt(hasLoopVariable(varDecl().bind(BadDecl))))))),
53 unless(equalsBoundNode(BadDecl)))
65 const auto *MatchedDecl = Result.Nodes.getNodeAs<VarDecl>(
"vardecl");
66 const ASTContext &Context = *Result.Context;
67 const SourceManager &Source = Context.getSourceManager();
70 if (MatchedDecl->isInvalidDecl())
88 if (MatchedDecl->getEndLoc().isMacroID())
91 const QualType TypePtr = MatchedDecl->getType();
92 std::optional<const char *> InitializationString;
93 bool AddMathInclude =
false;
95 if (TypePtr->isEnumeralType()) {
96 InitializationString =
nullptr;
97 }
else if (TypePtr->isBooleanType()) {
98 InitializationString =
" = false";
99 }
else if (TypePtr->isIntegerType()) {
100 InitializationString =
" = 0";
101 }
else if (TypePtr->isFloatingType()) {
102 InitializationString =
" = NAN";
103 AddMathInclude =
true;
104 }
else if (TypePtr->isAnyPointerType() || TypePtr->isMemberPointerType()) {
105 if (getLangOpts().CPlusPlus11)
106 InitializationString =
" = nullptr";
108 InitializationString =
" = NULL";
111 if (InitializationString) {
112 const auto Diagnostic =
113 diag(MatchedDecl->getLocation(),
"variable %0 is not initialized")
115 if (*InitializationString !=
nullptr)
116 Diagnostic << FixItHint::CreateInsertion(
118 *Result.SourceManager,
119 Result.Context->getLangOpts()),
120 *InitializationString);
121 if (AddMathInclude) {
122 Diagnostic << IncludeInserter.createIncludeInsertion(
123 Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader);
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.