24 using namespace clang;
29 :
public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> {
33 bool ReportNormalClones;
34 StringRef IgnoredFilesPattern;
38 mutable std::unique_ptr<BugType> BT_Exact, BT_Suspicious;
41 void checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
42 BugReporter &BR)
const;
45 AnalysisManager &Mgr, BugReporter &BR)
const;
48 void reportClones(BugReporter &BR, AnalysisManager &Mgr,
49 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
53 void reportSuspiciousClones(
54 BugReporter &BR, AnalysisManager &Mgr,
55 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
59 void CloneChecker::checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
60 BugReporter &BR)
const {
63 Detector.analyzeCodeBody(D);
68 BugReporter &BR)
const {
75 std::vector<CloneDetector::CloneGroup> AllCloneGroups;
83 reportSuspiciousClones(BR, Mgr, AllCloneGroups);
87 if (!ReportNormalClones)
96 reportClones(BR, Mgr, AllCloneGroups);
100 AnalysisManager &Mgr) {
107 void CloneChecker::reportClones(
108 BugReporter &BR, AnalysisManager &Mgr,
109 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
112 BT_Exact.reset(
new BugType(
this,
"Exact code clone",
"Code clone"));
117 auto R = llvm::make_unique<BugReport>(*BT_Exact,
"Duplicate code detected",
119 R->addRange(Group.front().getSourceRange());
121 for (
unsigned i = 1;
i < Group.size(); ++
i)
124 BR.emitReport(std::move(R));
128 void CloneChecker::reportSuspiciousClones(
129 BugReporter &BR, AnalysisManager &Mgr,
130 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
131 std::vector<VariablePattern::SuspiciousClonePair> Pairs;
134 for (
unsigned i = 0;
i < Group.size(); ++
i) {
137 for (
unsigned j = i + 1; j < Group.size(); ++j) {
150 Pairs.push_back(ClonePair);
159 new BugType(
this,
"Suspicious code clone",
"Code clone"));
172 auto R = llvm::make_unique<BugReport>(
174 "Potential copy-paste error; did you really mean to use '" +
175 Pair.FirstCloneInfo.Variable->getNameAsString() +
"' here?",
178 R->addRange(Pair.FirstCloneInfo.Mention->getSourceRange());
180 R->addNote(
"Similar code using '" +
181 Pair.SecondCloneInfo.Variable->getNameAsString() +
"' here",
184 Pair.SecondCloneInfo.Mention->getSourceRange());
186 BR.emitReport(std::move(R));
194 void ento::registerCloneChecker(CheckerManager &Mgr) {
195 auto *Checker = Mgr.registerChecker<CloneChecker>();
197 Checker->MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption(
198 Checker,
"MinimumCloneComplexity");
200 if (Checker->MinComplexity < 0)
201 Mgr.reportInvalidCheckerOptionValue(
202 Checker,
"MinimumCloneComplexity",
"a non-negative value");
204 Checker->ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
205 Checker,
"ReportNormalClones");
207 Checker->IgnoredFilesPattern = Mgr.getAnalyzerOptions()
208 .getCheckerStringOption(Checker,
"IgnoredFilesPattern");
211 bool ento::shouldRegisterCloneChecker(
const LangOptions &LO) {
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.