Implement the conditional-operator part of -Wsign-compare. Turn
DiagnoseSignCompare into Sema::CheckSignCompare and call it from more places.
Add some enumerator tests. These seem to expose some oddities in the
types we're converting C++ enumerators to; in particular, they're converting
to unsigned before int, which seems to contradict 4.5 [conv.prom] p2.
Note to self: stop baiting Doug in my commit messages.
llvm-svn: 86128
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index e974176..4c81cb1 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -1609,6 +1609,9 @@
void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
Expr **Args, unsigned NumArgs);
+ void CheckSignCompare(Expr *LHS, Expr *RHS, SourceLocation Loc,
+ const PartialDiagnostic &PD);
+
virtual ExpressionEvaluationContext
PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c9a28a7..f1d6f2b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3340,6 +3340,8 @@
if (getLangOptions().CPlusPlus)
return CXXCheckConditionalOperands(Cond, LHS, RHS, QuestionLoc);
+ CheckSignCompare(LHS, RHS, QuestionLoc, diag::warn_mixed_sign_conditional);
+
UsualUnaryConversions(Cond);
UsualUnaryConversions(LHS);
UsualUnaryConversions(RHS);
@@ -4428,8 +4430,8 @@
}
/// Implements -Wsign-compare.
-static void DiagnoseSignCompare(Sema &S, Expr *lex, Expr *rex,
- BinaryOperator::Opcode Opc, SourceLocation OpLoc) {
+void Sema::CheckSignCompare(Expr *lex, Expr *rex, SourceLocation OpLoc,
+ const PartialDiagnostic &PD) {
QualType lt = lex->getType(), rt = rex->getType();
// Only warn if both operands are integral.
@@ -4450,14 +4452,14 @@
// 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, S.Context)) {
+ if (signedOperand->isIntegerConstantExpr(value, Context)) {
assert(value.isSigned() && "result of signed expression not signed");
if (value.isNonNegative())
return;
}
- S.Diag(OpLoc, diag::warn_mixed_sign_comparison)
+ Diag(OpLoc, PD)
<< lex->getType() << rex->getType()
<< lex->getSourceRange() << rex->getSourceRange();
}
@@ -4470,7 +4472,7 @@
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
return CheckVectorCompareOperands(lex, rex, Loc, isRelational);
- DiagnoseSignCompare(*this, lex, rex, Opc, Loc);
+ CheckSignCompare(lex, rex, Loc, diag::warn_mixed_sign_comparison);
// C99 6.5.8p3 / C99 6.5.9p4
if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 6fdecc2..dc57681 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1603,6 +1603,8 @@
if (LHS->isTypeDependent() || RHS->isTypeDependent())
return Context.DependentTy;
+ CheckSignCompare(LHS, RHS, QuestionLoc, diag::warn_mixed_sign_conditional);
+
// C++0x 5.16p2
// If either the second or the third operand has type (cv) void, ...
QualType LTy = LHS->getType();