diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -964,33 +964,40 @@ const Expr *LHSExpr = B->getLHS()->IgnoreParens(); const Expr *RHSExpr = B->getRHS()->IgnoreParens(); - const IntegerLiteral *IntLiteral = dyn_cast(LHSExpr); - const Expr *BoolExpr = RHSExpr; + const Expr *BoolExpr = nullptr; // To store the expression. + Expr::EvalResult IntExprResult; // If integer literal then will save value. - if (!IntLiteral) { - IntLiteral = dyn_cast(RHSExpr); + if (LHSExpr->EvaluateAsInt(IntExprResult, *Context)) { + // Evaluating value. + BoolExpr = RHSExpr; + } + else if (RHSExpr->EvaluateAsInt(IntExprResult, *Context)) { BoolExpr = LHSExpr; } - - if (!IntLiteral) + else + { return TryResult(); + } const BinaryOperator *BitOp = dyn_cast(BoolExpr); if (BitOp && (BitOp->getOpcode() == BO_And || BitOp->getOpcode() == BO_Or)) { const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens(); const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens(); + + // If integer literal in expression identified then will save value. + Expr::EvalResult IntExprResult2; - const IntegerLiteral *IntLiteral2 = dyn_cast(LHSExpr2); - - if (!IntLiteral2) - IntLiteral2 = dyn_cast(RHSExpr2); - - if (!IntLiteral2) + + if (LHSExpr2->EvaluateAsInt(IntExprResult2, *Context)); + else if ( RHSExpr2->EvaluateAsInt(IntExprResult2, *Context)); + else return TryResult(); - llvm::APInt L1 = IntLiteral->getValue(); - llvm::APInt L2 = IntLiteral2->getValue(); + // Getting the values as integer from the evaluation expression to use for comparision. + llvm::APInt L1 = IntExprResult.Val.getInt(); + llvm::APInt L2 = IntExprResult2.Val.getInt(); + if ((BitOp->getOpcode() == BO_And && (L2 & L1) != L1) || (BitOp->getOpcode() == BO_Or && (L2 | L1) != L1)) { if (BuildOpts.Observer) @@ -999,7 +1006,7 @@ TryResult(B->getOpcode() != BO_EQ); } } else if (BoolExpr->isKnownToHaveBooleanValue()) { - llvm::APInt IntValue = IntLiteral->getValue(); + llvm::APInt IntValue = IntExprResult.Val.getInt(); // Getting the value. if ((IntValue == 1) || (IntValue == 0)) { return TryResult(); } diff --git a/clang/test/SemaCXX/warn-unreachable.cpp b/clang/test/SemaCXX/warn-unreachable.cpp --- a/clang/test/SemaCXX/warn-unreachable.cpp +++ b/clang/test/SemaCXX/warn-unreachable.cpp @@ -399,13 +399,13 @@ // TODO: Extend warning to the following code: if (x < -1) calledFun(); - if (x == -1) - calledFun(); + if (x == -1) // expected-note {{silence}} + calledFun(); // expected-warning {{will never be executed}} - if (x != -1) + if (x != -1) // expected-note {{silence}} calledFun(); else - calledFun(); + calledFun(); // expected-warning {{will never be executed}} if (-1 > x) calledFun(); else