24 using namespace clang;
29 :
public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> {
31 mutable std::unique_ptr<BugType> BT_Exact, BT_Suspicious;
34 void checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
35 BugReporter &BR)
const;
38 AnalysisManager &Mgr, BugReporter &BR)
const;
41 void reportClones(BugReporter &BR, AnalysisManager &Mgr,
42 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
46 void reportSuspiciousClones(
47 BugReporter &BR, AnalysisManager &Mgr,
48 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
52 void CloneChecker::checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
53 BugReporter &BR)
const {
56 Detector.analyzeCodeBody(D);
61 BugReporter &BR)
const {
65 int MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption(
66 "MinimumCloneComplexity", 50,
this);
67 assert(MinComplexity >= 0);
69 bool ReportSuspiciousClones = Mgr.getAnalyzerOptions()
70 .getCheckerBooleanOption(
"ReportSuspiciousClones",
true,
this);
72 bool ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
73 "ReportNormalClones",
true,
this);
75 StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions()
76 .getCheckerStringOption(
"IgnoredFilesPattern",
"",
this);
81 std::vector<CloneDetector::CloneGroup> AllCloneGroups;
89 if (ReportSuspiciousClones)
90 reportSuspiciousClones(BR, Mgr, AllCloneGroups);
94 if (!ReportNormalClones)
103 reportClones(BR, Mgr, AllCloneGroups);
107 AnalysisManager &Mgr) {
114 void CloneChecker::reportClones(
115 BugReporter &BR, AnalysisManager &Mgr,
116 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
119 BT_Exact.reset(
new BugType(
this,
"Exact code clone",
"Code clone"));
124 auto R = llvm::make_unique<BugReport>(*BT_Exact,
"Duplicate code detected",
126 R->addRange(Group.front().getSourceRange());
128 for (
unsigned i = 1; i < Group.size(); ++i)
129 R->addNote(
"Similar code here",
makeLocation(Group[i], Mgr),
131 BR.emitReport(std::move(R));
135 void CloneChecker::reportSuspiciousClones(
136 BugReporter &BR, AnalysisManager &Mgr,
137 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
138 std::vector<VariablePattern::SuspiciousClonePair> Pairs;
141 for (
unsigned i = 0; i < Group.size(); ++i) {
144 for (
unsigned j = i + 1; j < Group.size(); ++j) {
157 Pairs.push_back(ClonePair);
166 new BugType(
this,
"Suspicious code clone",
"Code clone"));
179 auto R = llvm::make_unique<BugReport>(
181 "Potential copy-paste error; did you really mean to use '" +
182 Pair.FirstCloneInfo.Variable->getNameAsString() +
"' here?",
185 R->addRange(Pair.FirstCloneInfo.Mention->getSourceRange());
187 R->addNote(
"Similar code using '" +
188 Pair.SecondCloneInfo.Variable->getNameAsString() +
"' here",
191 Pair.SecondCloneInfo.Mention->getSourceRange());
193 BR.emitReport(std::move(R));
201 void ento::registerCloneChecker(CheckerManager &Mgr) {
202 Mgr.registerChecker<CloneChecker>();
205 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.