From: Ted Kremenek Date: Fri, 18 Apr 2008 01:56:37 +0000 (+0000) Subject: Simplified internal logic of BugReporter, consolidating EmitWarning and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=75840e1501563fe7c3dcb5600b75965ba1fe1bc4;p=clang Simplified internal logic of BugReporter, consolidating EmitWarning and EmitPathWarning into one method. We now properly handle emitting warnings without a PathDiagnosticClient when the warning does not involve a particular statement. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49884 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index 2312583589..28f0f85d72 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -127,10 +127,8 @@ public: CFG& getCFG() { return getGraph().getCFG(); } - void EmitPathWarning(BugReport& R); - void EmitWarning(BugReport& R); - + void clearCache() { CachedErrors.clear(); } bool IsCached(ExplodedNode* N); diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp index 717f5b8d80..958f85dff9 100644 --- a/lib/Analysis/BasicObjCFoundationChecks.cpp +++ b/lib/Analysis/BasicObjCFoundationChecks.cpp @@ -190,7 +190,7 @@ static inline bool isNil(RVal X) { void BasicObjCFoundationChecks::EmitWarnings(BugReporter& BR) { for (ErrorsTy::iterator I=Errors.begin(), E=Errors.end(); I!=E; ++I) - BR.EmitPathWarning(**I); + BR.EmitWarning(**I); } bool BasicObjCFoundationChecks::CheckNilArg(NodeTy* N, unsigned Arg) { diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index d1689e2e51..294eb5faac 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -142,8 +142,10 @@ PathDiagnosticPiece* BugReport::VisitNode(ExplodedNode* N, void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R) { - ExplodedNode* N = R.getEndNode(); - assert (N && "Path diagnostic requires a ExplodedNode."); + ExplodedNode* N = R.getEndNode(); + + if (!N) + return; llvm::OwningPtr > GTrim(getGraph().Trim(&N, &N+1)); @@ -371,55 +373,51 @@ bool BugReporter::IsCached(ExplodedNode* N) { return false; } -void BugReporter::EmitPathWarning(BugReport& R) { - - ExplodedNode* N = R.getEndNode(); - - if (!PD || !N) { - EmitWarning(R); - return; - } - - if (IsCached(N)) +void BugReporter::EmitWarning(BugReport& R) { + + if (IsCached(R.getEndNode())) return; - + PathDiagnostic D(R.getName()); GeneratePathDiagnostic(D, R); + + // Emit a full diagnostic for the path if we have a PathDiagnosticClient. - if (!D.empty()) + if (PD && !D.empty()) { PD->HandlePathDiagnostic(D); -} - -void BugReporter::EmitWarning(BugReport& R) { - - ExplodedNode* N = R.getEndNode(); + return; + } - if (N && IsCached(N)) - return; + // We don't have a PathDiagnosticClient, but we can still emit a single + // line diagnostic. Determine the location. - FullSourceLoc L = R.getLocation(Ctx.getSourceManager()); + FullSourceLoc L = D.empty() ? R.getLocation(Ctx.getSourceManager()) + : D.back()->getLocation(); - const SourceRange *Beg, *End; - R.getRanges(Beg, End); - if (!PD) { + // Determine the range. - std::ostringstream os; - os << "[CHECKER] " << R.getDescription(); - - unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, - os.str().c_str()); - - Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg); - } - else { - PathDiagnostic D(R.getName()); - PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription()); - - for ( ; Beg != End; ++Beg) - piece->addRange(*Beg); - - D.push_back(piece); - PD->HandlePathDiagnostic(D); + const SourceRange *Beg, *End; + + if (!D.empty()) { + Beg = D.back()->ranges_begin(); + End = D.back()->ranges_end(); } + else + R.getRanges(Beg, End); + + // Compute the message. + + std::ostringstream os; + os << "[CHECKER] "; + + if (D.empty()) + os << R.getDescription(); + else + os << D.back()->getString(); + + unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, + os.str().c_str()); + + Diag.Report(L, ErrorDiag, NULL, 0, Beg, End - Beg); } diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 0cfd5771fa..fb11e4c357 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -1281,7 +1281,7 @@ void UseAfterRelease::EmitWarnings(BugReporter& BR) { RangedBugReport report(*this, I->first); report.addRange(I->second->getSourceRange()); - BR.EmitPathWarning(report); + BR.EmitWarning(report); } } @@ -1292,7 +1292,7 @@ void BadRelease::EmitWarnings(BugReporter& BR) { RangedBugReport report(*this, I->first); report.addRange(I->second->getSourceRange()); - BR.EmitPathWarning(report); + BR.EmitWarning(report); } } @@ -1303,7 +1303,7 @@ void Leak::EmitWarnings(BugReporter& BR) { E = TF.leaks_end(); I != E; ++I) { BugReport report(*this, I->second); - BR.EmitPathWarning(report); + BR.EmitWarning(report); } } diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp index c8805ab775..ea8762aa0c 100644 --- a/lib/Analysis/GRSimpleVals.cpp +++ b/lib/Analysis/GRSimpleVals.cpp @@ -45,7 +45,7 @@ void GenericEmitWarnings(BugReporter& BR, const BugType& D, for (; I != E; ++I) { BugReport R(D, GetNode(I)); - BR.EmitPathWarning(R); + BR.EmitWarning(R); } } @@ -182,7 +182,7 @@ public: report.addRange(I->second->getSourceRange()); // Emit the warning. - BR.EmitPathWarning(report); + BR.EmitWarning(report); } } @@ -209,7 +209,7 @@ public: report.addRange(I->second->getSourceRange()); // Emit the warning. - BR.EmitPathWarning(report); + BR.EmitWarning(report); } } }; @@ -240,7 +240,7 @@ public: report.addRange(E->getSourceRange()); // Emit the warning. - BR.EmitPathWarning(report); + BR.EmitWarning(report); } } };