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();