diff options
author | Chris Lattner <sabre@nondot.org> | 2010-07-24 01:10:11 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-07-24 01:10:11 +0000 |
commit | b7690b425845b636849f25074d64d30aad646473 (patch) | |
tree | 74e751ca9b31dfe691e2292227fe6d67337bf0d7 /lib | |
parent | 05b0f4195edf62af76795c92703a1d0c0fa936d9 (diff) |
turn down the logical bitwise confusion warning to not warn
when the RHS of the ||/&& is ever 0 or 1. This handles a variety of
creative idioms for "true" used in C programs and fixes many false
positives at the expense of a few false negatives. This fixes
rdar://8230351.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8b2e0203b3..5281f3ff79 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5819,18 +5819,21 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] // bitwise one. We do this when the LHS is a non-bool integer and the RHS // is a constant. if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() && - rex->getType()->isIntegerType() && rex->isEvaluatable(Context) && - // Don't warn if the RHS is a (constant folded) boolean expression like - // "sizeof(int) == 4". - !rex->isKnownToHaveBooleanValue() && + rex->getType()->isIntegerType() && // Don't warn in macros. - !Loc.isMacroID()) - Diag(Loc, diag::warn_logical_instead_of_bitwise) - << rex->getSourceRange() - << (Opc == BinaryOperator::LAnd ? "&&" : "||") - << (Opc == BinaryOperator::LAnd ? "&" : "|"); - - + !Loc.isMacroID()) { + // If the RHS can be constant folded, and if it constant folds to something + // that isn't 0 or 1 (which indicate a potential logical operation that + // happened to fold to true/false) then warn. + Expr::EvalResult Result; + if (rex->Evaluate(Result, Context) && !Result.HasSideEffects && + Result.Val.getInt() != 0 && Result.Val.getInt() != 1) { + Diag(Loc, diag::warn_logical_instead_of_bitwise) + << rex->getSourceRange() + << (Opc == BinaryOperator::LAnd ? "&&" : "||") + << (Opc == BinaryOperator::LAnd ? "&" : "|"); + } + } if (!Context.getLangOptions().CPlusPlus) { UsualUnaryConversions(lex); |