25 using namespace clang;
30 :
public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> {
32 mutable std::unique_ptr<BugType> BT_Exact, BT_Suspicious;
35 void checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
36 BugReporter &BR)
const;
39 AnalysisManager &Mgr, BugReporter &BR)
const;
42 void reportClones(BugReporter &BR, AnalysisManager &Mgr,
43 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
47 void reportSuspiciousClones(
48 BugReporter &BR, AnalysisManager &Mgr,
49 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
53 void CloneChecker::checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
54 BugReporter &BR)
const {
57 Detector.analyzeCodeBody(D);
62 BugReporter &BR)
const {
66 int MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption(
67 "MinimumCloneComplexity", 50,
this);
68 assert(MinComplexity >= 0);
70 bool ReportSuspiciousClones = Mgr.getAnalyzerOptions()
71 .getCheckerBooleanOption(
"ReportSuspiciousClones",
true,
this);
73 bool ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
74 "ReportNormalClones",
true,
this);
76 StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions()
77 .getCheckerStringOption(
"IgnoredFilesPattern",
"",
this);
82 std::vector<CloneDetector::CloneGroup> AllCloneGroups;
90 if (ReportSuspiciousClones)
91 reportSuspiciousClones(BR, Mgr, AllCloneGroups);
95 if (!ReportNormalClones)
104 reportClones(BR, Mgr, AllCloneGroups);
108 AnalysisManager &Mgr) {
115 void CloneChecker::reportClones(
116 BugReporter &BR, AnalysisManager &Mgr,
117 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
120 BT_Exact.reset(
new BugType(
this,
"Exact code clone",
"Code clone"));
125 auto R = llvm::make_unique<BugReport>(*BT_Exact,
"Duplicate code detected",
127 R->addRange(Group.front().getSourceRange());
129 for (
unsigned i = 1; i < Group.size(); ++i)
130 R->addNote(
"Similar code here",
makeLocation(Group[i], Mgr),
132 BR.emitReport(std::move(R));
136 void CloneChecker::reportSuspiciousClones(
137 BugReporter &BR, AnalysisManager &Mgr,
138 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
139 std::vector<VariablePattern::SuspiciousClonePair> Pairs;
142 for (
unsigned i = 0; i < Group.size(); ++i) {
145 for (
unsigned j = i + 1; j < Group.size(); ++j) {
158 Pairs.push_back(ClonePair);
167 new BugType(
this,
"Suspicious code clone",
"Code clone"));
180 auto R = llvm::make_unique<BugReport>(
182 "Potential copy-paste error; did you really mean to use '" +
183 Pair.FirstCloneInfo.Variable->getNameAsString() +
"' here?",
186 R->addRange(Pair.FirstCloneInfo.Mention->getSourceRange());
188 R->addNote(
"Similar code using '" +
189 Pair.SecondCloneInfo.Variable->getNameAsString() +
"' here",
192 Pair.SecondCloneInfo.Mention->getSourceRange());
194 BR.emitReport(std::move(R));
202 void ento::registerCloneChecker(CheckerManager &Mgr) {
203 Mgr.registerChecker<CloneChecker>();
Analyzes the pattern of the referenced variables in a statement.
Decl - This represents one declaration (or definition), e.g.
const Stmt * front() const
Returns the first statement in this sequence.
This file defines classes for searching and analyzing source code clones.
Identifies a list of statements.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
AnalysisDeclContext contains the context data for the function or method under analysis.
Ensures that all clones reference variables in the same pattern.
unsigned countPatternDifferences(const VariablePattern &Other, VariablePattern::SuspiciousClonePair *FirstMismatch=nullptr)
Counts the differences between this pattern and the given one.
Ensures that all clone groups contain at least the given amount of clones.
static void constrainClones(std::vector< CloneGroup > &CloneGroups, T C)
Constrains the given list of clone groups with the given constraint.
Defines the Diagnostic-related interfaces.
Searches for similar subtrees in the AST.
Describes two clones that reference their variables in a different pattern which could indicate a pro...
This constraint moves clones into clone groups of type II via hashing.
This constraint moves clones into clone groups of type II by comparing them.
Ensures that every clone has at least the given complexity.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Dataflow Directional Tag Classes.
static PathDiagnosticLocation makeLocation(const StmtSequence &S, AnalysisManager &Mgr)
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
The top declaration context.
This class handles loading and caching of source files into memory.
Ensures that no clone group fully contains another clone group.