diff options
author | John McCall <rjmccall@apple.com> | 2010-01-04 22:35:07 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-01-04 22:35:07 +0000 |
commit | b8e66c3b143b2057bde555468b4f7116f4e6eb55 (patch) | |
tree | 6482e28d17c10fc56b2095f42ebe0b7833c9549a /clang/lib | |
parent | ca15eaccbbb6fc6f8681c91a936731a823089bc9 (diff) | |
download | bcm5719-llvm-b8e66c3b143b2057bde555468b4f7116f4e6eb55.tar.gz bcm5719-llvm-b8e66c3b143b2057bde555468b4f7116f4e6eb55.zip |
-Wsign-compare shouldn't warn when the signed operand is a conditional operator
whose operands are non-negative integer constant expressions. This comes up
in LLVM in a few places.
llvm-svn: 92525
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a8be3339678..121ed6a8aba 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5110,6 +5110,22 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, return LHSTy; } +/// Returns true if we can prove that the result of the given +/// integral expression will not have its sign bit set. +static bool IsSignBitProvablyZero(ASTContext &Context, Expr *E) { + E = E->IgnoreParens(); + + llvm::APSInt value; + if (E->isIntegerConstantExpr(value, Context)) + return value.isNonNegative(); + + if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) + return IsSignBitProvablyZero(Context, CO->getLHS()) && + IsSignBitProvablyZero(Context, CO->getRHS()); + + return false; +} + /// \brief Implements -Wsign-compare. /// /// \param lex the left-hand expression @@ -5157,27 +5173,15 @@ void Sema::CheckSignCompare(Expr *lex, Expr *rex, SourceLocation OpLoc, // If the value is a non-negative integer constant, then the // signed->unsigned conversion won't change it. - llvm::APSInt value; - if (signedOperand->isIntegerConstantExpr(value, Context)) { - assert(value.isSigned() && "result of signed expression not signed"); - - if (value.isNonNegative()) - return; - } - - if (Equality) { - // For (in)equality comparisons, if the unsigned operand is a - // constant which cannot collide with a overflowed signed operand, - // then reinterpreting the signed operand as unsigned will not - // change the result of the comparison. - if (unsignedOperand->isIntegerConstantExpr(value, Context)) { - assert(!value.isSigned() && "result of unsigned expression is signed"); + if (IsSignBitProvablyZero(Context, signedOperand)) + return; - // 2's complement: test the top bit. - if (value.isNonNegative()) - return; - } - } + // For (in)equality comparisons, if the unsigned operand is a + // constant which cannot collide with a overflowed signed operand, + // then reinterpreting the signed operand as unsigned will not + // change the result of the comparison. + if (Equality && IsSignBitProvablyZero(Context, unsignedOperand)) + return; Diag(OpLoc, PD) << lex->getType() << rex->getType() |