19a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//== IdenticalExprChecker.cpp - Identical expression checker----------------==// 29a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// 39a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// The LLVM Compiler Infrastructure 49a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// 59a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// This file is distributed under the University of Illinois Open Source 69a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// License. See LICENSE.TXT for details. 79a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// 89a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//===----------------------------------------------------------------------===// 99a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// 109a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// \file 119a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// \brief This defines IdenticalExprChecker, a check that warns about 129a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// unintended use of identical expressions. 139a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// 14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// It checks for use of identical expressions with comparison operators and 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// inside conditional expressions. 169a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// 179a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//===----------------------------------------------------------------------===// 189a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 199a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose#include "ClangSACheckers.h" 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/RecursiveASTVisitor.h" 219a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 229a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose#include "clang/StaticAnalyzer/Core/Checker.h" 239a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose#include "clang/StaticAnalyzer/Core/CheckerManager.h" 249a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 259a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 269a7a568821b85cc83b80056268ef0dc32aecea12Jordan Roseusing namespace clang; 279a7a568821b85cc83b80056268ef0dc32aecea12Jordan Roseusing namespace ento; 289a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Stmt *Stmt2, bool IgnoreSideEffects = false); 319a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//===----------------------------------------------------------------------===// 329a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// FindIdenticalExprVisitor - Identify nodes using identical expressions. 339a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//===----------------------------------------------------------------------===// 349a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 3591934df3ce399e5938695b939943f92e7ff00483Benjamin Kramernamespace { 369a7a568821b85cc83b80056268ef0dc32aecea12Jordan Roseclass FindIdenticalExprVisitor 379a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose : public RecursiveASTVisitor<FindIdenticalExprVisitor> { 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BugReporter &BR; 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CheckerBase *Checker; 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalysisDeclContext *AC; 419a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rosepublic: 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines explicit FindIdenticalExprVisitor(BugReporter &B, 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CheckerBase *Checker, 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalysisDeclContext *A) 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : BR(B), Checker(Checker), AC(A) {} 469a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // FindIdenticalExprVisitor only visits nodes 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // that are binary operators, if statements or 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // conditional operators. 499a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose bool VisitBinaryOperator(const BinaryOperator *B); 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitIfStmt(const IfStmt *I); 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitConditionalOperator(const ConditionalOperator *C); 529a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 539a7a568821b85cc83b80056268ef0dc32aecea12Jordan Roseprivate: 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void reportIdenticalExpr(const BinaryOperator *B, bool CheckBitwise, 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<SourceRange> Sr); 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void checkBitwiseOrLogicalOp(const BinaryOperator *B, bool CheckBitwise); 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void checkComparisonOp(const BinaryOperator *B); 589a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose}; 5991934df3ce399e5938695b939943f92e7ff00483Benjamin Kramer} // end anonymous namespace 609a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid FindIdenticalExprVisitor::reportIdenticalExpr(const BinaryOperator *B, 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool CheckBitwise, 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<SourceRange> Sr) { 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Message; 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CheckBitwise) 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Message = "identical expressions on both sides of bitwise operator"; 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Message = "identical expressions on both sides of logical operator"; 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation ELoc = 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager()); 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BR.EmitBasicReport(AC->getDecl(), Checker, 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Use of identical expressions", 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines categories::LogicError, 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Message, ELoc, Sr); 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B, 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool CheckBitwise) { 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceRange Sr[2]; 81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *LHS = B->getLHS(); 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *RHS = B->getRHS(); 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Split operators as long as we still have operators to split on. We will 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // get called for every binary operator in an expression so there is no need 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // to check every one against each other here, just the right most one with 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // the others. 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (const BinaryOperator *B2 = dyn_cast<BinaryOperator>(LHS)) { 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (B->getOpcode() != B2->getOpcode()) 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isIdenticalStmt(AC->getASTContext(), RHS, B2->getRHS())) { 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sr[0] = RHS->getSourceRange(); 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sr[1] = B2->getRHS()->getSourceRange(); 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reportIdenticalExpr(B, CheckBitwise, Sr); 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LHS = B2->getLHS(); 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isIdenticalStmt(AC->getASTContext(), RHS, LHS)) { 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sr[0] = RHS->getSourceRange(); 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sr[1] = LHS->getSourceRange(); 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reportIdenticalExpr(B, CheckBitwise, Sr); 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) { 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Stmt *Stmt1 = I->getThen(); 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Stmt *Stmt2 = I->getElse(); 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check for identical conditions: 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // if (b) { 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // foo1(); 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // } else if (b) { 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // foo2(); 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // } 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Stmt1 && Stmt2) { 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *Cond1 = I->getCond(); 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Stmt *Else = Stmt2; 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (const IfStmt *I2 = dyn_cast_or_null<IfStmt>(Else)) { 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *Cond2 = I2->getCond(); 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isIdenticalStmt(AC->getASTContext(), Cond1, Cond2, false)) { 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceRange Sr = Cond1->getSourceRange(); 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation ELoc(Cond2, BR.getSourceManager(), AC); 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions", 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines categories::LogicError, 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "expression is identical to previous condition", 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ELoc, Sr); 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Else = I2->getElse(); 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Stmt1 || !Stmt2) 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Special handling for code like: 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // if (b) { 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // i = 1; 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // } else 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // i = 1; 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const CompoundStmt *CompStmt = dyn_cast<CompoundStmt>(Stmt1)) { 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CompStmt->size() == 1) 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Stmt1 = CompStmt->body_back(); 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const CompoundStmt *CompStmt = dyn_cast<CompoundStmt>(Stmt2)) { 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CompStmt->size() == 1) 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Stmt2 = CompStmt->body_back(); 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isIdenticalStmt(AC->getASTContext(), Stmt1, Stmt2, true)) { 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation ELoc = 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation::createBegin(I, BR.getSourceManager(), AC); 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BR.EmitBasicReport(AC->getDecl(), Checker, 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Identical branches", 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines categories::LogicError, 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "true and false branches are identical", ELoc); 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1649a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rosebool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) { 1659a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose BinaryOperator::Opcode Op = B->getOpcode(); 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BinaryOperator::isBitwiseOp(Op)) 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkBitwiseOrLogicalOp(B, true); 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BinaryOperator::isLogicalOp(Op)) 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkBitwiseOrLogicalOp(B, false); 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BinaryOperator::isComparisonOp(Op)) 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkComparisonOp(B); 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We want to visit ALL nodes (subexpressions of binary comparison 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // expressions too) that contains comparison operators. 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // True is always returned to traverse ALL nodes. 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) { 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BinaryOperator::Opcode Op = B->getOpcode(); 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1859a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // 1869a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // Special case for floating-point representation. 1879a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // 1889a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // If expressions on both sides of comparison operator are of type float, 1899a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // then for some comparison operators no warning shall be 1909a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // reported even if the expressions are identical from a symbolic point of 1919a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // view. Comparison between expressions, declared variables and literals 1929a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // are treated differently. 1939a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // 1949a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // != and == between float literals that have the same value should NOT warn. 1959a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // < > between float literals that have the same value SHOULD warn. 1969a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // 1979a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // != and == between the same float declaration should NOT warn. 1989a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // < > between the same float declaration SHOULD warn. 1999a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // 2009a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // != and == between eq. expressions that evaluates into float 2019a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // should NOT warn. 2029a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // < > between eq. expressions that evaluates into float 2039a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // should NOT warn. 2049a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // 2059a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose const Expr *LHS = B->getLHS()->IgnoreParenImpCasts(); 2069a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose const Expr *RHS = B->getRHS()->IgnoreParenImpCasts(); 2079a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 2089a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose const DeclRefExpr *DeclRef1 = dyn_cast<DeclRefExpr>(LHS); 2099a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose const DeclRefExpr *DeclRef2 = dyn_cast<DeclRefExpr>(RHS); 2109a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose const FloatingLiteral *FloatLit1 = dyn_cast<FloatingLiteral>(LHS); 2119a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose const FloatingLiteral *FloatLit2 = dyn_cast<FloatingLiteral>(RHS); 2129a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if ((DeclRef1) && (DeclRef2)) { 2139a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if ((DeclRef1->getType()->hasFloatingRepresentation()) && 2149a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose (DeclRef2->getType()->hasFloatingRepresentation())) { 2159a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if (DeclRef1->getDecl() == DeclRef2->getDecl()) { 2169a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if ((Op == BO_EQ) || (Op == BO_NE)) { 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2189a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 2199a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 2209a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 2219a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } else if ((FloatLit1) && (FloatLit2)) { 2229a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if (FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue())) { 2239a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if ((Op == BO_EQ) || (Op == BO_NE)) { 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2259a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 2269a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 2279a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } else if (LHS->getType()->hasFloatingRepresentation()) { 2289a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // If any side of comparison operator still has floating-point 2299a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // representation, then it's an expression. Don't warn. 2309a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // Here only LHS is checked since RHS will be implicit casted to float. 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2329a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } else { 2339a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose // No special case with floating-point representation, report as usual. 2349a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 2359a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isIdenticalStmt(AC->getASTContext(), B->getLHS(), B->getRHS())) { 2379a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose PathDiagnosticLocation ELoc = 2389a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager()); 2399a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose StringRef Message; 2409a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose if (((Op == BO_EQ) || (Op == BO_LE) || (Op == BO_GE))) 2419a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose Message = "comparison of identical expressions always evaluates to true"; 2429a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose else 2439a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose Message = "comparison of identical expressions always evaluates to false"; 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BR.EmitBasicReport(AC->getDecl(), Checker, 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Compare of identical expressions", 2469a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose categories::LogicError, Message, ELoc); 2479a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool FindIdenticalExprVisitor::VisitConditionalOperator( 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ConditionalOperator *C) { 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check if expressions in conditional expression are identical 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // from a symbolic point of view. 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (isIdenticalStmt(AC->getASTContext(), C->getTrueExpr(), 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines C->getFalseExpr(), true)) { 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation ELoc = 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PathDiagnosticLocation::createConditionalColonLoc( 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines C, BR.getSourceManager()); 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceRange Sr[2]; 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sr[0] = C->getTrueExpr()->getSourceRange(); 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Sr[1] = C->getFalseExpr()->getSourceRange(); 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BR.EmitBasicReport( 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AC->getDecl(), Checker, 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Identical expressions in conditional expression", 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines categories::LogicError, 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "identical expressions on both sides of ':' in conditional expression", 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ELoc, Sr); 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We want to visit ALL nodes (expressions in conditional 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // expressions too) that contains conditional operators, 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // thus always return true to traverse ALL nodes. 2759a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return true; 2769a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose} 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Determines whether two statement trees are identical regarding 2799a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// operators and symbols. 2809a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// 2819a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// Exceptions: expressions containing macros or functions with possible side 2829a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// effects are never considered identical. 2839a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// Limitations: (t + u) and (u + t) are not considered identical. 2849a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// t*(u + t) and t*u + t*t are not considered identical. 2859a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose/// 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Stmt *Stmt2, bool IgnoreSideEffects) { 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Stmt1 || !Stmt2) { 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Stmt1 && !Stmt2) 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 2929a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return false; 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If Stmt1 & Stmt2 are of different class then they are not 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // identical statements. 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Stmt1->getStmtClass() != Stmt2->getStmtClass()) 2989a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return false; 2999a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *Expr1 = dyn_cast<Expr>(Stmt1); 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Expr *Expr2 = dyn_cast<Expr>(Stmt2); 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Expr1 && Expr2) { 304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If Stmt1 has side effects then don't warn even if expressions 305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // are identical. 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!IgnoreSideEffects && Expr1->HasSideEffects(Ctx)) 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If either expression comes from a macro then don't warn even if 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // the expressions are identical. 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if ((Expr1->getExprLoc().isMacroID()) || (Expr2->getExprLoc().isMacroID())) 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If all children of two expressions are identical, return true. 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Expr::const_child_iterator I1 = Expr1->child_begin(); 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Expr::const_child_iterator I2 = Expr2->child_begin(); 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (I1 != Expr1->child_end() && I2 != Expr2->child_end()) { 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!*I1 || !*I2 || !isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects)) 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++I1; 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++I2; 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If there are different number of children in the statements, return 323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // false. 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I1 != Expr1->child_end()) 325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I2 != Expr2->child_end()) 327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (Stmt1->getStmtClass()) { 3319a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose default: 3329a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return false; 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::CallExprClass: 3349a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::ArraySubscriptExprClass: 3359a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::ImplicitCastExprClass: 3369a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::ParenExprClass: 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::BreakStmtClass: 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::ContinueStmtClass: 339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::NullStmtClass: 340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::CStyleCastExprClass: { 342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CStyleCastExpr* CastExpr1 = cast<CStyleCastExpr>(Stmt1); 343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CStyleCastExpr* CastExpr2 = cast<CStyleCastExpr>(Stmt2); 344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return CastExpr1->getTypeAsWritten() == CastExpr2->getTypeAsWritten(); 346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::ReturnStmtClass: { 348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ReturnStmt *ReturnStmt1 = cast<ReturnStmt>(Stmt1); 349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ReturnStmt *ReturnStmt2 = cast<ReturnStmt>(Stmt2); 350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isIdenticalStmt(Ctx, ReturnStmt1->getRetValue(), 352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnStmt2->getRetValue(), IgnoreSideEffects); 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::ForStmtClass: { 355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ForStmt *ForStmt1 = cast<ForStmt>(Stmt1); 356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ForStmt *ForStmt2 = cast<ForStmt>(Stmt2); 357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, ForStmt1->getInit(), ForStmt2->getInit(), 359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, ForStmt1->getCond(), ForStmt2->getCond(), 362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, ForStmt1->getInc(), ForStmt2->getInc(), 365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, ForStmt1->getBody(), ForStmt2->getBody(), 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::DoStmtClass: { 373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DoStmt *DStmt1 = cast<DoStmt>(Stmt1); 374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DoStmt *DStmt2 = cast<DoStmt>(Stmt2); 375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, DStmt1->getCond(), DStmt2->getCond(), 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, DStmt1->getBody(), DStmt2->getBody(), 380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::WhileStmtClass: { 385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const WhileStmt *WStmt1 = cast<WhileStmt>(Stmt1); 386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const WhileStmt *WStmt2 = cast<WhileStmt>(Stmt2); 387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, WStmt1->getCond(), WStmt2->getCond(), 389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, WStmt1->getBody(), WStmt2->getBody(), 392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 3949a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return true; 395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::IfStmtClass: { 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const IfStmt *IStmt1 = cast<IfStmt>(Stmt1); 398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const IfStmt *IStmt2 = cast<IfStmt>(Stmt2); 399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, IStmt1->getCond(), IStmt2->getCond(), 401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, IStmt1->getThen(), IStmt2->getThen(), 404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, IStmt1->getElse(), IStmt2->getElse(), 407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IgnoreSideEffects)) 408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::CompoundStmtClass: { 412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CompoundStmt *CompStmt1 = cast<CompoundStmt>(Stmt1); 413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CompoundStmt *CompStmt2 = cast<CompoundStmt>(Stmt2); 414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CompStmt1->size() != CompStmt2->size()) 416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CompoundStmt::const_body_iterator I1 = CompStmt1->body_begin(); 419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CompoundStmt::const_body_iterator I2 = CompStmt2->body_begin(); 420651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines while (I1 != CompStmt1->body_end() && I2 != CompStmt2->body_end()) { 421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects)) 422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++I1; 424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ++I2; 425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::CompoundAssignOperatorClass: 4309a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::BinaryOperatorClass: { 431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const BinaryOperator *BinOp1 = cast<BinaryOperator>(Stmt1); 432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const BinaryOperator *BinOp2 = cast<BinaryOperator>(Stmt2); 4339a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return BinOp1->getOpcode() == BinOp2->getOpcode(); 4349a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4359a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::CharacterLiteralClass: { 436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CharacterLiteral *CharLit1 = cast<CharacterLiteral>(Stmt1); 437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CharacterLiteral *CharLit2 = cast<CharacterLiteral>(Stmt2); 4389a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return CharLit1->getValue() == CharLit2->getValue(); 4399a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4409a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::DeclRefExprClass: { 441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DeclRefExpr *DeclRef1 = cast<DeclRefExpr>(Stmt1); 442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DeclRefExpr *DeclRef2 = cast<DeclRefExpr>(Stmt2); 4439a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return DeclRef1->getDecl() == DeclRef2->getDecl(); 4449a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4459a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::IntegerLiteralClass: { 446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const IntegerLiteral *IntLit1 = cast<IntegerLiteral>(Stmt1); 447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const IntegerLiteral *IntLit2 = cast<IntegerLiteral>(Stmt2); 4489a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return IntLit1->getValue() == IntLit2->getValue(); 4499a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4509a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::FloatingLiteralClass: { 451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FloatingLiteral *FloatLit1 = cast<FloatingLiteral>(Stmt1); 452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FloatingLiteral *FloatLit2 = cast<FloatingLiteral>(Stmt2); 4539a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose return FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue()); 4549a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::StringLiteralClass: { 456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const StringLiteral *StringLit1 = cast<StringLiteral>(Stmt1); 457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const StringLiteral *StringLit2 = cast<StringLiteral>(Stmt2); 458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return StringLit1->getString() == StringLit2->getString(); 459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4609a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::MemberExprClass: { 461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const MemberExpr *MemberStmt1 = cast<MemberExpr>(Stmt1); 462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const MemberExpr *MemberStmt2 = cast<MemberExpr>(Stmt2); 463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MemberStmt1->getMemberDecl() == MemberStmt2->getMemberDecl(); 4649a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4659a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose case Stmt::UnaryOperatorClass: { 466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const UnaryOperator *UnaryOp1 = cast<UnaryOperator>(Stmt1); 467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const UnaryOperator *UnaryOp2 = cast<UnaryOperator>(Stmt2); 468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return UnaryOp1->getOpcode() == UnaryOp2->getOpcode(); 4699a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4709a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4719a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose} 4729a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 4739a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//===----------------------------------------------------------------------===// 4749a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose// FindIdenticalExprChecker 4759a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose//===----------------------------------------------------------------------===// 4769a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 47791934df3ce399e5938695b939943f92e7ff00483Benjamin Kramernamespace { 4789a7a568821b85cc83b80056268ef0dc32aecea12Jordan Roseclass FindIdenticalExprChecker : public Checker<check::ASTCodeBody> { 4799a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rosepublic: 4809a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, 4819a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose BugReporter &BR) const { 482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FindIdenticalExprVisitor Visitor(BR, this, Mgr.getAnalysisDeclContext(D)); 4839a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose Visitor.TraverseDecl(const_cast<Decl *>(D)); 4849a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose } 4859a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose}; 48691934df3ce399e5938695b939943f92e7ff00483Benjamin Kramer} // end anonymous namespace 4879a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose 4889a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rosevoid ento::registerIdenticalExprChecker(CheckerManager &Mgr) { 4899a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose Mgr.registerChecker<FindIdenticalExprChecker>(); 4909a7a568821b85cc83b80056268ef0dc32aecea12Jordan Rose} 491