================ @@ -102,6 +102,211 @@ void BranchCloneCheck::registerMatchers(MatchFinder *Finder) { this); Finder->addMatcher(switchStmt().bind("switch"), this); Finder->addMatcher(conditionalOperator().bind("condOp"), this); + Finder->addMatcher( + ifStmt((hasThen(hasDescendant(ifStmt())))).bind("ifWithDescendantIf"), + this); +} + +/// Determines whether two statement trees are identical regarding +/// operators and symbols. +/// +/// Exceptions: expressions containing macros or functions with possible side +/// effects are never considered identical. +/// Limitations: (t + u) and (u + t) are not considered identical. +/// t*(u + t) and t*u + t*t are not considered identical. +/// +static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, + const Stmt *Stmt2, bool IgnoreSideEffects) { + + if (!Stmt1 || !Stmt2) + return !Stmt1 && !Stmt2; + + // If Stmt1 & Stmt2 are of different class then they are not + // identical statements. + if (Stmt1->getStmtClass() != Stmt2->getStmtClass()) + return false; + + const auto *Expr1 = dyn_cast<Expr>(Stmt1); + const auto *Expr2 = dyn_cast<Expr>(Stmt2); + + if (Expr1 && Expr2) { + // If Stmt1 has side effects then don't warn even if expressions + // are identical. + if (!IgnoreSideEffects && Expr1->HasSideEffects(Ctx)) + return false; + // If either expression comes from a macro then don't warn even if + // the expressions are identical. + if ((Expr1->getExprLoc().isMacroID()) || (Expr2->getExprLoc().isMacroID())) + return false; + + // If all children of two expressions are identical, return true. + Expr::const_child_iterator I1 = Expr1->child_begin(); + Expr::const_child_iterator I2 = Expr2->child_begin(); + while (I1 != Expr1->child_end() && I2 != Expr2->child_end()) { + if (!*I1 || !*I2 || !isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects)) ---------------- HerrCai0907 wrote:
`!*I1 || !*I2` already be handled in `isIdenticalStmt` https://github.com/llvm/llvm-project/pull/114715 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits