diff options
author | Vitaly Buka <vitalybuka@google.com> | 2016-10-04 02:40:35 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2016-10-04 02:40:35 +0000 |
commit | 1a8d52d1aef01644b5597d410a3e450e293c12b3 (patch) | |
tree | 55337e2b28c890eecdcdb913343759862ed69935 /clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp | |
parent | b3814f6f38cc0b3d0d9662c01b8a6d49a6543219 (diff) | |
download | bcm5719-llvm-1a8d52d1aef01644b5597d410a3e450e293c12b3.tar.gz bcm5719-llvm-1a8d52d1aef01644b5597d410a3e450e293c12b3.zip |
Revert "[analyzer] Improve CloneChecker diagnostics" as its depends on reverted r283092
This reverts commit r283094.
llvm-svn: 283182
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp | 106 |
1 files changed, 50 insertions, 56 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp index 6fa5732d10c..b4ac223c022 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CloneChecker.cpp @@ -16,10 +16,8 @@ #include "ClangSACheckers.h" #include "clang/Analysis/CloneDetection.h" #include "clang/Basic/Diagnostic.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" using namespace clang; @@ -29,7 +27,6 @@ namespace { class CloneChecker : public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> { mutable CloneDetector Detector; - mutable std::unique_ptr<BugType> BT_Exact, BT_Suspicious; public: void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, @@ -39,12 +36,12 @@ public: AnalysisManager &Mgr, BugReporter &BR) const; /// \brief Reports all clones to the user. - void reportClones(BugReporter &BR, AnalysisManager &Mgr, + void reportClones(SourceManager &SM, AnalysisManager &Mgr, int MinComplexity) const; /// \brief Reports only suspicious clones to the user along with informaton /// that explain why they are suspicious. - void reportSuspiciousClones(BugReporter &BR, AnalysisManager &Mgr, + void reportSuspiciousClones(SourceManager &SM, AnalysisManager &Mgr, int MinComplexity) const; }; } // end anonymous namespace @@ -73,82 +70,79 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU, "ReportNormalClones", true, this); if (ReportSuspiciousClones) - reportSuspiciousClones(BR, Mgr, MinComplexity); + reportSuspiciousClones(BR.getSourceManager(), Mgr, MinComplexity); if (ReportNormalClones) - reportClones(BR, Mgr, MinComplexity); + reportClones(BR.getSourceManager(), Mgr, MinComplexity); } -static PathDiagnosticLocation makeLocation(const StmtSequence &S, - AnalysisManager &Mgr) { - ASTContext &ACtx = Mgr.getASTContext(); - return PathDiagnosticLocation::createBegin( - S.front(), ACtx.getSourceManager(), - Mgr.getAnalysisDeclContext(ACtx.getTranslationUnitDecl())); -} - -void CloneChecker::reportClones(BugReporter &BR, AnalysisManager &Mgr, +void CloneChecker::reportClones(SourceManager &SM, AnalysisManager &Mgr, int MinComplexity) const { std::vector<CloneDetector::CloneGroup> CloneGroups; Detector.findClones(CloneGroups, MinComplexity); - if (!BT_Exact) - BT_Exact.reset(new BugType(this, "Exact code clone", "Code clone")); + DiagnosticsEngine &DiagEngine = Mgr.getDiagnostic(); + + unsigned WarnID = DiagEngine.getCustomDiagID(DiagnosticsEngine::Warning, + "Detected code clone."); + + unsigned NoteID = DiagEngine.getCustomDiagID(DiagnosticsEngine::Note, + "Related code clone is here."); for (CloneDetector::CloneGroup &Group : CloneGroups) { // We group the clones by printing the first as a warning and all others // as a note. - auto R = llvm::make_unique<BugReport>( - *BT_Exact, "Duplicate code detected", - makeLocation(Group.Sequences.front(), Mgr)); - R->addRange(Group.Sequences.front().getSourceRange()); - - for (unsigned i = 1; i < Group.Sequences.size(); ++i) - R->addNote("Similar code here", - makeLocation(Group.Sequences[i], Mgr), - Group.Sequences[i].getSourceRange()); - BR.emitReport(std::move(R)); + DiagEngine.Report(Group.Sequences.front().getStartLoc(), WarnID); + for (unsigned i = 1; i < Group.Sequences.size(); ++i) { + DiagEngine.Report(Group.Sequences[i].getStartLoc(), NoteID); + } } } -void CloneChecker::reportSuspiciousClones(BugReporter &BR, +void CloneChecker::reportSuspiciousClones(SourceManager &SM, AnalysisManager &Mgr, int MinComplexity) const { std::vector<CloneDetector::SuspiciousClonePair> Clones; Detector.findSuspiciousClones(Clones, MinComplexity); - if (!BT_Suspicious) - BT_Suspicious.reset( - new BugType(this, "Suspicious code clone", "Code clone")); + DiagnosticsEngine &DiagEngine = Mgr.getDiagnostic(); + + auto SuspiciousCloneWarning = DiagEngine.getCustomDiagID( + DiagnosticsEngine::Warning, "suspicious code clone detected; did you " + "mean to use %0?"); + + auto RelatedCloneNote = DiagEngine.getCustomDiagID( + DiagnosticsEngine::Note, "suggestion is based on the usage of this " + "variable in a similar piece of code"); - ASTContext &ACtx = BR.getContext(); - SourceManager &SM = ACtx.getSourceManager(); - AnalysisDeclContext *ADC = - Mgr.getAnalysisDeclContext(ACtx.getTranslationUnitDecl()); + auto RelatedSuspiciousCloneNote = DiagEngine.getCustomDiagID( + DiagnosticsEngine::Note, "suggestion is based on the usage of this " + "variable in a similar piece of code; did you " + "mean to use %0?"); for (CloneDetector::SuspiciousClonePair &Pair : Clones) { - // FIXME: We are ignoring the suggestions currently, because they are - // only 50% accurate (even if the second suggestion is unavailable), - // which may confuse the user. - // Think how to perform more accurate suggestions? - - auto R = llvm::make_unique<BugReport>( - *BT_Suspicious, - "Potential copy-paste error; did you really mean to use '" + - Pair.FirstCloneInfo.Variable->getNameAsString() + "' here?", - PathDiagnosticLocation::createBegin(Pair.FirstCloneInfo.Mention, SM, - ADC)); - R->addRange(Pair.FirstCloneInfo.Mention->getSourceRange()); - - R->addNote("Similar code using '" + - Pair.SecondCloneInfo.Variable->getNameAsString() + "' here", - PathDiagnosticLocation::createBegin(Pair.SecondCloneInfo.Mention, - SM, ADC), - Pair.SecondCloneInfo.Mention->getSourceRange()); - - BR.emitReport(std::move(R)); + // The first clone always has a suggestion and we report it to the user + // along with the place where the suggestion should be used. + DiagEngine.Report(Pair.FirstCloneInfo.VarRange.getBegin(), + SuspiciousCloneWarning) + << Pair.FirstCloneInfo.VarRange << Pair.FirstCloneInfo.Suggestion; + + // The second clone can have a suggestion and if there is one, we report + // that suggestion to the user. + if (Pair.SecondCloneInfo.Suggestion) { + DiagEngine.Report(Pair.SecondCloneInfo.VarRange.getBegin(), + RelatedSuspiciousCloneNote) + << Pair.SecondCloneInfo.VarRange << Pair.SecondCloneInfo.Suggestion; + continue; + } + + // If there isn't a suggestion in the second clone, we only inform the + // user where we got the idea that his code could contain an error. + DiagEngine.Report(Pair.SecondCloneInfo.VarRange.getBegin(), + RelatedCloneNote) + << Pair.SecondCloneInfo.VarRange; } } |