From 9a7a568821b85cc83b80056268ef0dc32aecea12 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 8 Nov 2013 01:15:39 +0000 Subject: [PATCH] [analyzer] Add IdenticalExprChecker, to find copy-pasted code. This syntactic checker looks for expressions on both sides of comparison operators that are structurally the same. As a special case, the floating-point idiom "x != x" for "isnan(x)" is left alone. Currently this only checks comparison operators, but in the future we could extend this to include logical operators or chained if-conditionals. Checker by Per Viberg! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194236 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Checkers/CMakeLists.txt | 1 + lib/StaticAnalyzer/Checkers/Checkers.td | 4 + .../Checkers/IdenticalExprChecker.cpp | 222 +++++ test/Analysis/array-struct-region.cpp | 2 +- test/Analysis/identical-expressions.cpp | 942 ++++++++++++++++++ 5 files changed, 1170 insertions(+), 1 deletion(-) create mode 100644 lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp create mode 100644 test/Analysis/identical-expressions.cpp diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 392995e291..ebd3377802 100644 --- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -33,6 +33,7 @@ add_clang_library(clangStaticAnalyzerCheckers FixedAddressChecker.cpp GenericTaintChecker.cpp IdempotentOperationChecker.cpp + IdenticalExprChecker.cpp IvarInvalidationChecker.cpp LLVMConventionsChecker.cpp MacOSKeychainAPIChecker.cpp diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td index cc25ae5e8d..862212d532 100644 --- a/lib/StaticAnalyzer/Checkers/Checkers.td +++ b/lib/StaticAnalyzer/Checkers/Checkers.td @@ -100,6 +100,10 @@ def CastToStructChecker : Checker<"CastToStruct">, HelpText<"Check for cast from non-struct pointer to struct pointer">, DescFile<"CastToStructChecker.cpp">; +def IdenticalExprChecker : Checker<"IdenticalExpr">, + HelpText<"Warn about unintended use of identical expressions in operators">, + DescFile<"IdenticalExprChecker.cpp">; + def FixedAddressChecker : Checker<"FixedAddr">, HelpText<"Check for assignment of a fixed address to a pointer">, DescFile<"FixedAddressChecker.cpp">; diff --git a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp new file mode 100644 index 0000000000..6f5f7bdbc9 --- /dev/null +++ b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -0,0 +1,222 @@ +//== IdenticalExprChecker.cpp - Identical expression checker----------------==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This defines IdenticalExprChecker, a check that warns about +/// unintended use of identical expressions. +/// +/// It checks for use of identical expressions with comparison operators. +/// +//===----------------------------------------------------------------------===// + +#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/AST/RecursiveASTVisitor.h" + +using namespace clang; +using namespace ento; + +static bool isIdenticalExpr(const ASTContext &Ctx, const Expr *Expr1, + const Expr *Expr2); +//===----------------------------------------------------------------------===// +// FindIdenticalExprVisitor - Identify nodes using identical expressions. +//===----------------------------------------------------------------------===// + +class FindIdenticalExprVisitor + : public RecursiveASTVisitor { +public: + explicit FindIdenticalExprVisitor(BugReporter &B, AnalysisDeclContext *A) + : BR(B), AC(A) {} + // FindIdenticalExprVisitor only visits nodes + // that are binary operators. + bool VisitBinaryOperator(const BinaryOperator *B); + +private: + BugReporter &BR; + AnalysisDeclContext *AC; +}; + +bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) { + BinaryOperator::Opcode Op = B->getOpcode(); + if (!BinaryOperator::isComparisonOp(Op)) + return true; + // + // Special case for floating-point representation. + // + // If expressions on both sides of comparison operator are of type float, + // then for some comparison operators no warning shall be + // reported even if the expressions are identical from a symbolic point of + // view. Comparison between expressions, declared variables and literals + // are treated differently. + // + // != and == between float literals that have the same value should NOT warn. + // < > between float literals that have the same value SHOULD warn. + // + // != and == between the same float declaration should NOT warn. + // < > between the same float declaration SHOULD warn. + // + // != and == between eq. expressions that evaluates into float + // should NOT warn. + // < > between eq. expressions that evaluates into float + // should NOT warn. + // + const Expr *LHS = B->getLHS()->IgnoreParenImpCasts(); + const Expr *RHS = B->getRHS()->IgnoreParenImpCasts(); + + const DeclRefExpr *DeclRef1 = dyn_cast(LHS); + const DeclRefExpr *DeclRef2 = dyn_cast(RHS); + const FloatingLiteral *FloatLit1 = dyn_cast(LHS); + const FloatingLiteral *FloatLit2 = dyn_cast(RHS); + if ((DeclRef1) && (DeclRef2)) { + if ((DeclRef1->getType()->hasFloatingRepresentation()) && + (DeclRef2->getType()->hasFloatingRepresentation())) { + if (DeclRef1->getDecl() == DeclRef2->getDecl()) { + if ((Op == BO_EQ) || (Op == BO_NE)) { + return true; + } + } + } + } else if ((FloatLit1) && (FloatLit2)) { + if (FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue())) { + if ((Op == BO_EQ) || (Op == BO_NE)) { + return true; + } + } + } else if (LHS->getType()->hasFloatingRepresentation()) { + // If any side of comparison operator still has floating-point + // representation, then it's an expression. Don't warn. + // Here only LHS is checked since RHS will be implicit casted to float. + return true; + } else { + // No special case with floating-point representation, report as usual. + } + + if (isIdenticalExpr(AC->getASTContext(), B->getLHS(), B->getRHS())) { + PathDiagnosticLocation ELoc = + PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager()); + StringRef Message; + if (((Op == BO_EQ) || (Op == BO_LE) || (Op == BO_GE))) + Message = "comparison of identical expressions always evaluates to true"; + else + Message = "comparison of identical expressions always evaluates to false"; + BR.EmitBasicReport(AC->getDecl(), "Compare of identical expressions", + categories::LogicError, Message, ELoc); + } + // We want to visit ALL nodes (subexpressions of binary comparison + // expressions too) that contains comparison operators. + // True is always returned to traverse ALL nodes. + return true; +} +/// \brief Determines whether two expression 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 isIdenticalExpr(const ASTContext &Ctx, const Expr *Expr1, + const Expr *Expr2) { + // If Expr1 & Expr2 are of different class then they are not + // identical expression. + if (Expr1->getStmtClass() != Expr2->getStmtClass()) + return false; + // If Expr1 has side effects then don't warn even if expressions + // are identical. + if (Expr1->HasSideEffects(Ctx)) + return false; + // Is expression is based on 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()) { + const Expr *Child1 = dyn_cast(*I1); + const Expr *Child2 = dyn_cast(*I2); + if (!Child1 || !Child2 || !isIdenticalExpr(Ctx, Child1, Child2)) + return false; + ++I1; + ++I2; + } + // If there are different number of children in the expressions, return false. + // (TODO: check if this is a redundant condition.) + if (I1 != Expr1->child_end()) + return false; + if (I2 != Expr2->child_end()) + return false; + + switch (Expr1->getStmtClass()) { + default: + return false; + case Stmt::ArraySubscriptExprClass: + case Stmt::CStyleCastExprClass: + case Stmt::ImplicitCastExprClass: + case Stmt::ParenExprClass: + return true; + case Stmt::BinaryOperatorClass: { + const BinaryOperator *BinOp1 = dyn_cast(Expr1); + const BinaryOperator *BinOp2 = dyn_cast(Expr2); + return BinOp1->getOpcode() == BinOp2->getOpcode(); + } + case Stmt::CharacterLiteralClass: { + const CharacterLiteral *CharLit1 = dyn_cast(Expr1); + const CharacterLiteral *CharLit2 = dyn_cast(Expr2); + return CharLit1->getValue() == CharLit2->getValue(); + } + case Stmt::DeclRefExprClass: { + const DeclRefExpr *DeclRef1 = dyn_cast(Expr1); + const DeclRefExpr *DeclRef2 = dyn_cast(Expr2); + return DeclRef1->getDecl() == DeclRef2->getDecl(); + } + case Stmt::IntegerLiteralClass: { + const IntegerLiteral *IntLit1 = dyn_cast(Expr1); + const IntegerLiteral *IntLit2 = dyn_cast(Expr2); + return IntLit1->getValue() == IntLit2->getValue(); + } + case Stmt::FloatingLiteralClass: { + const FloatingLiteral *FloatLit1 = dyn_cast(Expr1); + const FloatingLiteral *FloatLit2 = dyn_cast(Expr2); + return FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue()); + } + case Stmt::MemberExprClass: { + const MemberExpr *MemberExpr1 = dyn_cast(Expr1); + const MemberExpr *MemberExpr2 = dyn_cast(Expr2); + return MemberExpr1->getMemberDecl() == MemberExpr2->getMemberDecl(); + } + case Stmt::UnaryOperatorClass: { + const UnaryOperator *UnaryOp1 = dyn_cast(Expr1); + const UnaryOperator *UnaryOp2 = dyn_cast(Expr2); + if (UnaryOp1->getOpcode() != UnaryOp2->getOpcode()) + return false; + return !UnaryOp1->isIncrementDecrementOp(); + } + } +} + +//===----------------------------------------------------------------------===// +// FindIdenticalExprChecker +//===----------------------------------------------------------------------===// + +class FindIdenticalExprChecker : public Checker { +public: + void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, + BugReporter &BR) const { + FindIdenticalExprVisitor Visitor(BR, Mgr.getAnalysisDeclContext(D)); + Visitor.TraverseDecl(const_cast(D)); + } +}; + +void ento::registerIdenticalExprChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); +} diff --git a/test/Analysis/array-struct-region.cpp b/test/Analysis/array-struct-region.cpp index a776d7da50..47776863d6 100644 --- a/test/Analysis/array-struct-region.cpp +++ b/test/Analysis/array-struct-region.cpp @@ -21,7 +21,7 @@ struct S { #if __cplusplus const struct S *operator -(const struct S &s) { return &s; } -bool operator ~(const struct S &s) { return &s != &s; } +bool operator ~(const struct S &s) { return (&s) != &s; } #endif diff --git a/test/Analysis/identical-expressions.cpp b/test/Analysis/identical-expressions.cpp new file mode 100644 index 0000000000..50f341d393 --- /dev/null +++ b/test/Analysis/identical-expressions.cpp @@ -0,0 +1,942 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.IdenticalExpr -verify %s + +/* Only one expected warning per function allowed at the very end. */ + +/* '!=' operator*/ + +/* '!=' with float */ +int checkNotEqualFloatLiteralCompare1(void) { + return (5.14F != 5.14F); // no warning +} + +int checkNotEqualFloatLiteralCompare2(void) { + return (6.14F != 7.14F); // no warning +} + +int checkNotEqualFloatDeclCompare1(void) { + float f = 7.1F; + float g = 7.1F; + return (f != g); // no warning +} + +int checkNotEqualFloatDeclCompare12(void) { + float f = 7.1F; + return (f != f); // no warning +} + +int checkNotEqualFloatDeclCompare3(void) { + float f = 7.1F; + return (f != 7.1F); // no warning +} + +int checkNotEqualFloatDeclCompare4(void) { + float f = 7.1F; + return (7.1F != f); // no warning +} + +int checkNotEqualFloatDeclCompare5(void) { + float f = 7.1F; + int t = 7; + return (t != f); // no warning +} + +int checkNotEqualFloatDeclCompare6(void) { + float f = 7.1F; + int t = 7; + return (f != t); // no warning +} + + + +int checkNotEqualCastFloatDeclCompare11(void) { + float f = 7.1F; + return ((int)f != (int)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkNotEqualCastFloatDeclCompare12(void) { + float f = 7.1F; + return ((char)f != (int)f); // no warning +} +int checkNotEqualBinaryOpFloatCompare1(void) { + int res; + float f= 3.14F; + res = (f + 3.14F != f + 3.14F); // no warning + return (0); +} +int checkNotEqualBinaryOpFloatCompare2(void) { + float f = 7.1F; + float g = 7.1F; + return (f + 3.14F != g + 3.14F); // no warning +} +int checkNotEqualBinaryOpFloatCompare3(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F != (int)f + 3.14F); // no warning + return (0); +} +int checkNotEqualBinaryOpFloatCompare4(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F != (char)f + 3.14F); // no warning + return (0); +} + +int checkNotEqualNestedBinaryOpFloatCompare1(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (3.14F - u)*t) != ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkNotEqualNestedBinaryOpFloatCompare2(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) != ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkNotEqualNestedBinaryOpFloatCompare3(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) != ((int)f + (3.14F - u)*(f + t != f + t))); // no warning + return (0); +} + + + + +/* end '!=' with float*/ + +/* '!=' with int*/ + +int checkNotEqualIntLiteralCompare1(void) { + return (5 != 5); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + +int checkNotEqualIntLiteralCompare2(void) { + return (6 != 7); // no warning +} + +int checkNotEqualIntDeclCompare1(void) { + int f = 7; + int g = 7; + return (f != g); // no warning +} + +int checkNotEqualIntDeclCompare3(void) { + int f = 7; + return (f != 7); // no warning +} + +int checkNotEqualIntDeclCompare4(void) { + int f = 7; + return (7 != f); // no warning +} + +int checkNotEqualCastIntDeclCompare11(void) { + int f = 7; + return ((int)f != (int)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkNotEqualCastIntDeclCompare12(void) { + int f = 7; + return ((char)f != (int)f); // no warning +} +int checkNotEqualBinaryOpIntCompare1(void) { + int res; + int t= 1; + int u= 2; + int f= 4; + res = (f + 4 != f + 4); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkNotEqualBinaryOpIntCompare2(void) { + int f = 7; + int g = 7; + return (f + 4 != g + 4); // no warning +} + + +int checkNotEqualBinaryOpIntCompare3(void) { + int res; + int t= 1; + int u= 2; + int f= 4; + res = ((int)f + 4 != (int)f + 4); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkNotEqualBinaryOpIntCompare4(void) { + int res; + int t= 1; + int u= 2; + int f= 4; + res = ((int)f + 4 != (char)f + 4); // no warning + return (0); +} +int checkNotEqualBinaryOpIntCompare5(void) { + int res; + int t= 1; + int u= 2; + res = (u + t != u + t); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +int checkNotEqualNestedBinaryOpIntCompare1(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (3 - u)*t) != ((int)f + (3 - u)*t)); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +int checkNotEqualNestedBinaryOpIntCompare2(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) != ((int)f + (3 - u)*t)); // no warning + return (0); +} + +int checkNotEqualNestedBinaryOpIntCompare3(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) != ((int)f + (3 - u)*(t + 1 != t + 1))); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +/* end '!=' int */ + + + +/* '!=' with int pointer */ + +int checkNotEqualIntPointerLiteralCompare1(void) { + int* p = 0; + return (p != 0); // no warning +} + +int checkNotEqualIntPointerLiteralCompare2(void) { + return (6 != 7); // no warning +} + +int checkNotEqualIntPointerDeclCompare1(void) { + int k = 3; + int* f = &k; + int* g = &k; + return (f != g); // no warning +} + +int checkNotEqualCastIntPointerDeclCompare11(void) { + int k = 7; + int* f = &k; + return ((int*)f != (int*)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkNotEqualCastIntPointerDeclCompare12(void) { + int k = 7; + int* f = &k; + return ((int*)((char*)f) != (int*)f); // no warning +} +int checkNotEqualBinaryOpIntPointerCompare1(void) { + int k = 7; + int res; + int* f= &k; + res = (f + 4 != f + 4); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkNotEqualBinaryOpIntPointerCompare2(void) { + int k = 7; + int* f = &k; + int* g = &k; + return (f + 4 != g + 4); // no warning +} + + +int checkNotEqualBinaryOpIntPointerCompare3(void) { + int k = 7; + int res; + int* f= &k; + res = ((int*)f + 4 != (int*)f + 4); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkNotEqualBinaryOpIntPointerCompare4(void) { + int k = 7; + int res; + int* f= &k; + res = ((int*)f + 4 != (int*)((char*)f) + 4); // no warning + return (0); +} + +int checkNotEqualNestedBinaryOpIntPointerCompare1(void) { + int res; + int k = 7; + int t= 1; + int* u= &k+2; + int* f= &k+3; + res = ((f + (3)*t) != (f + (3)*t)); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +int checkNotEqualNestedBinaryOpIntPointerCompare2(void) { + int res; + int k = 7; + int t= 1; + int* u= &k+2; + int* f= &k+3; + res = (((3)*t + f) != (f + (3)*t)); // no warning + return (0); +} +/* end '!=' int* */ + +/* end '!=' */ + + + +/* EQ operator */ + +int checkEqualIntPointerDeclCompare(void) { + int k = 3; + int* f = &k; + int* g = &k; + return (f == g); // no warning +} + +int checkEqualIntPointerDeclCompare0(void) { + int k = 3; + int* f = &k; + return (f+1 == f+1); // expected-warning {{comparison of identical expressions always evaluates to true}} +} + +/* EQ with float*/ + +int checkEqualFloatLiteralCompare1(void) { + return (5.14F == 5.14F); // no warning +} + +int checkEqualFloatLiteralCompare2(void) { + return (6.14F == 7.14F); // no warning +} + +int checkEqualFloatDeclCompare1(void) { + float f = 7.1F; + float g = 7.1F; + return (f == g); // no warning +} + +int checkEqualFloatDeclCompare12(void) { + float f = 7.1F; + return (f == f); // no warning +} + + +int checkEqualFloatDeclCompare3(void) { + float f = 7.1F; + return (f == 7.1F); // no warning +} + +int checkEqualFloatDeclCompare4(void) { + float f = 7.1F; + return (7.1F == f); // no warning +} + +int checkEqualFloatDeclCompare5(void) { + float f = 7.1F; + int t = 7; + return (t == f); // no warning +} + +int checkEqualFloatDeclCompare6(void) { + float f = 7.1F; + int t = 7; + return (f == t); // no warning +} + + + + +int checkEqualCastFloatDeclCompare11(void) { + float f = 7.1F; + return ((int)f == (int)f); // expected-warning {{comparison of identical expressions always evaluates to true}} +} +int checkEqualCastFloatDeclCompare12(void) { + float f = 7.1F; + return ((char)f == (int)f); // no warning +} +int checkEqualBinaryOpFloatCompare1(void) { + int res; + float f= 3.14F; + res = (f + 3.14F == f + 3.14F); // no warning + return (0); +} +int checkEqualBinaryOpFloatCompare2(void) { + float f = 7.1F; + float g = 7.1F; + return (f + 3.14F == g + 3.14F); // no warning +} +int checkEqualBinaryOpFloatCompare3(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F == (int)f + 3.14F); // no warning + return (0); +} +int checkEqualBinaryOpFloatCompare4(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F == (char)f + 3.14F); // no warning + return (0); +} + +int checkEqualNestedBinaryOpFloatCompare1(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (3.14F - u)*t) == ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkEqualNestedBinaryOpFloatCompare2(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) == ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkEqualNestedBinaryOpFloatCompare3(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) == ((int)f + (3.14F - u)*(f + t == f + t))); // no warning + return (0); +} + + + + + +/* Equal with int*/ + +int checkEqualIntLiteralCompare1(void) { + return (5 == 5); // expected-warning {{comparison of identical expressions always evaluates to true}} +} + +int checkEqualIntLiteralCompare2(void) { + return (6 == 7); // no warning +} + +int checkEqualIntDeclCompare1(void) { + int f = 7; + int g = 7; + return (f == g); // no warning +} + +int checkEqualCastIntDeclCompare11(void) { + int f = 7; + return ((int)f == (int)f); // expected-warning {{comparison of identical expressions always evaluates to true}} +} +int checkEqualCastIntDeclCompare12(void) { + int f = 7; + return ((char)f == (int)f); // no warning +} + +int checkEqualIntDeclCompare3(void) { + int f = 7; + return (f == 7); // no warning +} + +int checkEqualIntDeclCompare4(void) { + int f = 7; + return (7 == f); // no warning +} + +int checkEqualBinaryOpIntCompare1(void) { + int res; + int t= 1; + int u= 2; + int f= 4; + res = (f + 4 == f + 4); // expected-warning {{comparison of identical expressions always evaluates to true}} + return (0); +} +int checkEqualBinaryOpIntCompare2(void) { + int f = 7; + int g = 7; + return (f + 4 == g + 4); // no warning +} + + +int checkEqualBinaryOpIntCompare3(void) { + int res; + int t= 1; + int u= 2; + int f= 4; + res = ((int)f + 4 == (int)f + 4); // expected-warning {{comparison of identical expressions always evaluates to true}} + return (0); + +} +int checkEqualBinaryOpIntCompare4(void) { + int res; + int t= 1; + int u= 2; + int f= 4; + res = ((int)f + 4 == (char)f + 4); // no warning + return (0); +} +int checkEqualBinaryOpIntCompare5(void) { + int res; + int t= 1; + int u= 2; + res = (u + t == u + t); // expected-warning {{comparison of identical expressions always evaluates to true}} + return (0); +} + +int checkEqualNestedBinaryOpIntCompare1(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (3 - u)*t) == ((int)f + (3 - u)*t)); // expected-warning {{comparison of identical expressions always evaluates to true}} + return (0); +} + +int checkEqualNestedBinaryOpIntCompare2(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) == ((int)f + (3 - u)*t)); // no warning + return (0); +} + +int checkEqualNestedBinaryOpIntCompare3(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) == ((int)f + (3 - u)*(t + 1 == t + 1))); // expected-warning {{comparison of identical expressions always evaluates to true}} + return (0); +} + + +/* end EQ int */ + +/* end EQ */ + + +/* LT */ + +/* LT with float */ + +int checkLessThanFloatLiteralCompare1(void) { + return (5.14F < 5.14F); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + +int checkLessThanFloatLiteralCompare2(void) { + return (6.14F < 7.14F); // no warning +} + +int checkLessThanFloatDeclCompare1(void) { + float f = 7.1F; + float g = 7.1F; + return (f < g); // no warning +} + +int checkLessThanFloatDeclCompare12(void) { + float f = 7.1F; + return (f < f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + +int checkLessThanFloatDeclCompare3(void) { + float f = 7.1F; + return (f < 7.1F); // no warning +} + +int checkLessThanFloatDeclCompare4(void) { + float f = 7.1F; + return (7.1F < f); // no warning +} + +int checkLessThanFloatDeclCompare5(void) { + float f = 7.1F; + int t = 7; + return (t < f); // no warning +} + +int checkLessThanFloatDeclCompare6(void) { + float f = 7.1F; + int t = 7; + return (f < t); // no warning +} + + +int checkLessThanCastFloatDeclCompare11(void) { + float f = 7.1F; + return ((int)f < (int)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkLessThanCastFloatDeclCompare12(void) { + float f = 7.1F; + return ((char)f < (int)f); // no warning +} +int checkLessThanBinaryOpFloatCompare1(void) { + int res; + float f= 3.14F; + res = (f + 3.14F < f + 3.14F); // no warning + return (0); +} +int checkLessThanBinaryOpFloatCompare2(void) { + float f = 7.1F; + float g = 7.1F; + return (f + 3.14F < g + 3.14F); // no warning +} +int checkLessThanBinaryOpFloatCompare3(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F < (int)f + 3.14F); // no warning + return (0); +} +int checkLessThanBinaryOpFloatCompare4(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F < (char)f + 3.14F); // no warning + return (0); +} + +int checkLessThanNestedBinaryOpFloatCompare1(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (3.14F - u)*t) < ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkLessThanNestedBinaryOpFloatCompare2(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) < ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkLessThanNestedBinaryOpFloatCompare3(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) < ((int)f + (3.14F - u)*(f + t < f + t))); // no warning + return (0); +} + +/* end LT with float */ + +/* LT with int */ + + +int checkLessThanIntLiteralCompare1(void) { + return (5 < 5); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + +int checkLessThanIntLiteralCompare2(void) { + return (6 < 7); // no warning +} + +int checkLessThanIntDeclCompare1(void) { + int f = 7; + int g = 7; + return (f < g); // no warning +} + +int checkLessThanIntDeclCompare3(void) { + int f = 7; + return (f < 7); // no warning +} + +int checkLessThanIntDeclCompare4(void) { + int f = 7; + return (7 < f); // no warning +} + +int checkLessThanIntDeclCompare5(void) { + int f = 7; + int t = 7; + return (t < f); // no warning +} + +int checkLessThanIntDeclCompare6(void) { + int f = 7; + int t = 7; + return (f < t); // no warning +} + +int checkLessThanCastIntDeclCompare11(void) { + int f = 7; + return ((int)f < (int)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkLessThanCastIntDeclCompare12(void) { + int f = 7; + return ((char)f < (int)f); // no warning +} +int checkLessThanBinaryOpIntCompare1(void) { + int res; + int f= 3; + res = (f + 3 < f + 3); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkLessThanBinaryOpIntCompare2(void) { + int f = 7; + int g = 7; + return (f + 3 < g + 3); // no warning +} +int checkLessThanBinaryOpIntCompare3(void) { + int res; + int f= 3; + res = ((int)f + 3 < (int)f + 3); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkLessThanBinaryOpIntCompare4(void) { + int res; + int f= 3; + res = ((int)f + 3 < (char)f + 3); // no warning + return (0); +} + +int checkLessThanNestedBinaryOpIntCompare1(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (3 - u)*t) < ((int)f + (3 - u)*t)); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +int checkLessThanNestedBinaryOpIntCompare2(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) < ((int)f + (3 - u)*t)); // no warning + return (0); +} + +int checkLessThanNestedBinaryOpIntCompare3(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) < ((int)f + (3 - u)*(t + u < t + u))); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +/* end LT with int */ + +/* end LT */ + + +/* GT */ + +/* GT with float */ + +int checkGreaterThanFloatLiteralCompare1(void) { + return (5.14F > 5.14F); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + +int checkGreaterThanFloatLiteralCompare2(void) { + return (6.14F > 7.14F); // no warning +} + +int checkGreaterThanFloatDeclCompare1(void) { + float f = 7.1F; + float g = 7.1F; + + return (f > g); // no warning +} + +int checkGreaterThanFloatDeclCompare12(void) { + float f = 7.1F; + return (f > f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + + +int checkGreaterThanFloatDeclCompare3(void) { + float f = 7.1F; + return (f > 7.1F); // no warning +} + +int checkGreaterThanFloatDeclCompare4(void) { + float f = 7.1F; + return (7.1F > f); // no warning +} + +int checkGreaterThanFloatDeclCompare5(void) { + float f = 7.1F; + int t = 7; + return (t > f); // no warning +} + +int checkGreaterThanFloatDeclCompare6(void) { + float f = 7.1F; + int t = 7; + return (f > t); // no warning +} + +int checkGreaterThanCastFloatDeclCompare11(void) { + float f = 7.1F; + return ((int)f > (int)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkGreaterThanCastFloatDeclCompare12(void) { + float f = 7.1F; + return ((char)f > (int)f); // no warning +} +int checkGreaterThanBinaryOpFloatCompare1(void) { + int res; + float f= 3.14F; + res = (f + 3.14F > f + 3.14F); // no warning + return (0); +} +int checkGreaterThanBinaryOpFloatCompare2(void) { + float f = 7.1F; + float g = 7.1F; + return (f + 3.14F > g + 3.14F); // no warning +} +int checkGreaterThanBinaryOpFloatCompare3(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F > (int)f + 3.14F); // no warning + return (0); +} +int checkGreaterThanBinaryOpFloatCompare4(void) { + int res; + float f= 3.14F; + res = ((int)f + 3.14F > (char)f + 3.14F); // no warning + return (0); +} + +int checkGreaterThanNestedBinaryOpFloatCompare1(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (3.14F - u)*t) > ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkGreaterThanNestedBinaryOpFloatCompare2(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) > ((int)f + (3.14F - u)*t)); // no warning + return (0); +} + +int checkGreaterThanNestedBinaryOpFloatCompare3(void) { + int res; + int t= 1; + int u= 2; + float f= 3.14F; + res = (((int)f + (u - 3.14F)*t) > ((int)f + (3.14F - u)*(f + t > f + t))); // no warning + return (0); +} + +/* end GT with float */ + +/* GT with int */ + + +int checkGreaterThanIntLiteralCompare1(void) { + return (5 > 5); // expected-warning {{comparison of identical expressions always evaluates to false}} +} + +int checkGreaterThanIntLiteralCompare2(void) { + return (6 > 7); // no warning +} + +int checkGreaterThanIntDeclCompare1(void) { + int f = 7; + int g = 7; + + return (f > g); // no warning +} + +int checkGreaterThanIntDeclCompare3(void) { + int f = 7; + return (f > 7); // no warning +} + +int checkGreaterThanIntDeclCompare4(void) { + int f = 7; + return (7 > f); // no warning +} + +int checkGreaterThanCastIntDeclCompare11(void) { + int f = 7; + return ((int)f > (int)f); // expected-warning {{comparison of identical expressions always evaluates to false}} +} +int checkGreaterThanCastIntDeclCompare12(void) { + int f = 7; + return ((char)f > (int)f); // no warning +} +int checkGreaterThanBinaryOpIntCompare1(void) { + int res; + int f= 3; + res = (f + 3 > f + 3); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkGreaterThanBinaryOpIntCompare2(void) { + int f = 7; + int g = 7; + return (f + 3 > g + 3); // no warning +} +int checkGreaterThanBinaryOpIntCompare3(void) { + int res; + int f= 3; + res = ((int)f + 3 > (int)f + 3); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} +int checkGreaterThanBinaryOpIntCompare4(void) { + int res; + int f= 3; + res = ((int)f + 3 > (char)f + 3); // no warning + return (0); +} + +int checkGreaterThanNestedBinaryOpIntCompare1(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (3 - u)*t) > ((int)f + (3 - u)*t)); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +int checkGreaterThanNestedBinaryOpIntCompare2(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) > ((int)f + (3 - u)*t)); // no warning + return (0); +} + +int checkGreaterThanNestedBinaryOpIntCompare3(void) { + int res; + int t= 1; + int u= 2; + int f= 3; + res = (((int)f + (u - 3)*t) > ((int)f + (3 - u)*(t + u > t + u))); // expected-warning {{comparison of identical expressions always evaluates to false}} + return (0); +} + +/* end GT with int */ + +/* end GT */ -- 2.40.0