7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " BranchCloneCheck.h"
10
+ #include " ../utils/ASTUtils.h"
10
11
#include " clang/AST/ASTContext.h"
11
12
#include " clang/ASTMatchers/ASTMatchFinder.h"
12
13
#include " clang/Analysis/CloneDetection.h"
16
17
using namespace clang ;
17
18
using namespace clang ::ast_matchers;
18
19
19
- // / Returns true when the statements are Type I clones of each other.
20
- static bool areStatementsIdentical (const Stmt *LHS, const Stmt *RHS,
21
- const ASTContext &Context) {
22
- if (isa<Expr>(LHS) && isa<Expr>(RHS)) {
23
- // If we have errors in expressions, we will be unable
24
- // to accurately profile and compute hashes for each
25
- // of the left and right statements.
26
- const auto *LHSExpr = llvm::cast<Expr>(LHS);
27
- const auto *RHSExpr = llvm::cast<Expr>(RHS);
28
- if (LHSExpr->containsErrors () && RHSExpr->containsErrors ()) {
29
- return false ;
30
- }
31
- }
32
-
33
- llvm::FoldingSetNodeID DataLHS, DataRHS;
34
- LHS->Profile (DataLHS, Context, false );
35
- RHS->Profile (DataRHS, Context, false );
36
- return (DataLHS == DataRHS);
37
- }
38
-
39
20
namespace {
40
21
// / A branch in a switch may consist of several statements; while a branch in
41
22
// / an if/else if/else chain is one statement (which may be a CompoundStmt).
@@ -55,8 +36,9 @@ static bool areSwitchBranchesIdentical(const SwitchBranch LHS,
55
36
// NOTE: We strip goto labels and annotations in addition to stripping
56
37
// the `case X:` or `default:` labels, but it is very unlikely that this
57
38
// would cause false positives in real-world code.
58
- if (!areStatementsIdentical (LHS[I]->stripLabelLikeStatements (),
59
- RHS[I]->stripLabelLikeStatements (), Context)) {
39
+ if (!tidy::utils::areStatementsIdentical (LHS[I]->stripLabelLikeStatements (),
40
+ RHS[I]->stripLabelLikeStatements (),
41
+ Context)) {
60
42
return false ;
61
43
}
62
44
}
@@ -89,8 +71,8 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) {
89
71
90
72
if (!isa<IfStmt>(Else)) {
91
73
// Just a simple if with no `else if` branch.
92
- if (areStatementsIdentical (Then->IgnoreContainers (),
93
- Else->IgnoreContainers (), Context)) {
74
+ if (utils:: areStatementsIdentical (Then->IgnoreContainers (),
75
+ Else->IgnoreContainers (), Context)) {
94
76
diag (IS->getBeginLoc (), " if with identical then and else branches" );
95
77
diag (IS->getElseLoc (), " else branch starts here" , DiagnosticIDs::Note);
96
78
}
@@ -130,9 +112,9 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) {
130
112
int NumCopies = 1 ;
131
113
132
114
for (size_t J = I + 1 ; J < N; J++) {
133
- if (KnownAsClone[J] ||
134
- ! areStatementsIdentical ( Branches[I]->IgnoreContainers (),
135
- Branches[J]->IgnoreContainers (), Context))
115
+ if (KnownAsClone[J] || ! utils::areStatementsIdentical (
116
+ Branches[I]->IgnoreContainers (),
117
+ Branches[J]->IgnoreContainers (), Context))
136
118
continue ;
137
119
138
120
NumCopies++;
@@ -160,7 +142,8 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) {
160
142
161
143
if (const auto *CO = Result.Nodes .getNodeAs <ConditionalOperator>(" condOp" )) {
162
144
// We do not try to detect chains of ?: operators.
163
- if (areStatementsIdentical (CO->getTrueExpr (), CO->getFalseExpr (), Context))
145
+ if (utils::areStatementsIdentical (CO->getTrueExpr (), CO->getFalseExpr (),
146
+ Context))
164
147
diag (CO->getQuestionLoc (),
165
148
" conditional operator with identical true and false expressions" );
166
149
0 commit comments