forked from OSchip/llvm-project
-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
This commit is contained in:
parent
ca15eaccbb
commit
b8e66c3b14
|
@ -5110,6 +5110,22 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||||
return LHSTy;
|
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.
|
/// \brief Implements -Wsign-compare.
|
||||||
///
|
///
|
||||||
/// \param lex the left-hand expression
|
/// \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
|
// If the value is a non-negative integer constant, then the
|
||||||
// signed->unsigned conversion won't change it.
|
// signed->unsigned conversion won't change it.
|
||||||
llvm::APSInt value;
|
if (IsSignBitProvablyZero(Context, signedOperand))
|
||||||
if (signedOperand->isIntegerConstantExpr(value, Context)) {
|
return;
|
||||||
assert(value.isSigned() && "result of signed expression not signed");
|
|
||||||
|
|
||||||
if (value.isNonNegative())
|
// For (in)equality comparisons, if the unsigned operand is a
|
||||||
return;
|
// 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) {
|
if (Equality && IsSignBitProvablyZero(Context, unsignedOperand))
|
||||||
// For (in)equality comparisons, if the unsigned operand is a
|
return;
|
||||||
// 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");
|
|
||||||
|
|
||||||
// 2's complement: test the top bit.
|
|
||||||
if (value.isNonNegative())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Diag(OpLoc, PD)
|
Diag(OpLoc, PD)
|
||||||
<< lex->getType() << rex->getType()
|
<< lex->getType() << rex->getType()
|
||||||
|
|
|
@ -194,6 +194,9 @@ int ints(long a, unsigned long b) {
|
||||||
((short) a < (unsigned short) 0x80000) + // expected-warning {{comparison of integers of different signs}}
|
((short) a < (unsigned short) 0x80000) + // expected-warning {{comparison of integers of different signs}}
|
||||||
((signed char) a < (unsigned char) 0x80000) + // expected-warning {{comparison of integers of different signs}}
|
((signed char) a < (unsigned char) 0x80000) + // expected-warning {{comparison of integers of different signs}}
|
||||||
|
|
||||||
|
// We should be able to avoid warning about this.
|
||||||
|
(b != (a < 4 ? 1 : 2)) +
|
||||||
|
|
||||||
10
|
10
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue