Improve the -Wsign-compare heuristics:
  * If the unsigned type is smaller than the signed type, never warn, because
    its value will not change when zero-extended to the larger type.
  * If we're testing for (in)equality, and the unsigned value is an integer
    constant whose sign bit is not set, never warn, because even though the
    signed value might change, it can't affect the result of the equality.

Also make the comparison test cases much more rigorous, and have them expose
the subtle differences between C and C++ here.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86242 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index c4de6be..cad06d7 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1610,7 +1610,8 @@
                              Expr **Args, unsigned NumArgs);
 
   void CheckSignCompare(Expr *LHS, Expr *RHS, SourceLocation Loc,
-                        const PartialDiagnostic &PD);
+                        const PartialDiagnostic &PD,
+                        bool Equality = false);
 
   virtual ExpressionEvaluationContext
   PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 031bbe7..d92f4b9 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4445,9 +4445,15 @@
   return LHSTy;
 }
 
-/// Implements -Wsign-compare.
+/// \brief Implements -Wsign-compare.
+///
+/// \param lex the left-hand expression
+/// \param rex the right-hand expression
+/// \param OpLoc the location of the joining operator
+/// \param Equality whether this is an "equality-like" join;
+///   this suppresses the warning in some cases
 void Sema::CheckSignCompare(Expr *lex, Expr *rex, SourceLocation OpLoc,
-                            const PartialDiagnostic &PD) {
+                            const PartialDiagnostic &PD, bool Equality) {
   QualType lt = lex->getType(), rt = rex->getType();
 
   // Only warn if both operands are integral.
@@ -4461,15 +4467,25 @@
 
   // The rule is that the signed operand becomes unsigned, so isolate the
   // signed operand.
-  Expr *signedOperand;
+  Expr *signedOperand, *unsignedOperand;
   if (lt->isSignedIntegerType()) {
     if (rt->isSignedIntegerType()) return;
     signedOperand = lex;
+    unsignedOperand = rex;
   } else {
     if (!rt->isSignedIntegerType()) return;
     signedOperand = rex;
+    unsignedOperand = lex;
   }
 
+  // If the unsigned type is strictly smaller than the signed type,
+  // then (1) the result type will be signed and (2) the unsigned type
+  // will fight losslessly within the signed type, and so the result
+  // of the comparison will be exact.
+  if (Context.getIntWidth(signedOperand->getType()) >
+      Context.getIntWidth(unsignedOperand->getType()))
+    return;
+
   // If the value is a non-negative integer constant, then the
   // signed->unsigned conversion won't change it.
   llvm::APSInt value;
@@ -4480,6 +4496,20 @@
       return;
   }
 
+  if (Equality) {
+    // For (in)equality comparisons, if the unsigned operand is a
+    // constant no greater than the maximum 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)
     << lex->getType() << rex->getType()
     << lex->getSourceRange() << rex->getSourceRange();
@@ -4493,7 +4523,8 @@
   if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
     return CheckVectorCompareOperands(lex, rex, Loc, isRelational);
 
-  CheckSignCompare(lex, rex, Loc, diag::warn_mixed_sign_comparison);
+  CheckSignCompare(lex, rex, Loc, diag::warn_mixed_sign_comparison,
+                   (Opc == BinaryOperator::EQ || Opc == BinaryOperator::NE));
 
   // C99 6.5.8p3 / C99 6.5.9p4
   if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType())
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
index 45a100b..9d7168d 100644
--- a/test/Sema/compare.c
+++ b/test/Sema/compare.c
@@ -8,23 +8,194 @@
 }
 
 int ints(long a, unsigned long b) {
-  return (a == b) +        // expected-warning {{comparison of integers of different signs}}
-         ((int)a == b) +   // expected-warning {{comparison of integers of different signs}}
-         ((short)a == b) + // expected-warning {{comparison of integers of different signs}}
-         (a == (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
-         (a == (unsigned short) b); // expected-warning {{comparison of integers of different signs}}
+  enum EnumA {A};
+  enum EnumB {B};
+  enum EnumC {C = 0x10000};
+  return
+         // (a,b)
+         (a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a == (unsigned int) b) +
+         (a == (unsigned short) b) +
+         (a == (unsigned char) b) +
+         ((long) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) b) +
+         (a < (unsigned short) b) +
+         (a < (unsigned char) b) +
+         ((long) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
 
-  enum Enum {B};
-  return (a == B) +
-         ((int)a == B) +
-         ((short)a == B) +
-         (a == (unsigned int) B) +  // expected-warning {{comparison of integers of different signs}}
-         (a == (unsigned short) B); // expected-warning {{comparison of integers of different signs}}         
+         // (A,b)
+         (A == (unsigned long) b) +
+         (A == (unsigned int) b) +
+         (A == (unsigned short) b) +
+         (A == (unsigned char) b) +
+         ((long) A == b) +
+         ((int) A == b) +
+         ((short) A == b) +
+         ((signed char) A == b) +
+         ((long) A == (unsigned long) b) +
+         ((int) A == (unsigned int) b) +
+         ((short) A == (unsigned short) b) +
+         ((signed char) A == (unsigned char) b) +
+         (A < (unsigned long) b) +
+         (A < (unsigned int) b) +
+         (A < (unsigned short) b) +
+         (A < (unsigned char) b) +
+         ((long) A < b) +
+         ((int) A < b) +
+         ((short) A < b) +
+         ((signed char) A < b) +
+         ((long) A < (unsigned long) b) +
+         ((int) A < (unsigned int) b) +
+         ((short) A < (unsigned short) b) +
+         ((signed char) A < (unsigned char) b) +
 
-  // Should be able to prove all of these are non-negative.
-  return (b == (long) B) +
-         (b == (int) B) +
-         (b == (short) B);
+         // (a,B)
+         (a == (unsigned long) B) +
+         (a == (unsigned int) B) +
+         (a == (unsigned short) B) +
+         (a == (unsigned char) B) +
+         ((long) a == B) +
+         ((int) a == B) +
+         ((short) a == B) +
+         ((signed char) a == B) +
+         ((long) a == (unsigned long) B) +
+         ((int) a == (unsigned int) B) +
+         ((short) a == (unsigned short) B) +
+         ((signed char) a == (unsigned char) B) +
+         (a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) B) +
+         (a < (unsigned short) B) +
+         (a < (unsigned char) B) +
+         ((long) a < B) +
+         ((int) a < B) +
+         ((short) a < B) +
+         ((signed char) a < B) +
+         ((long) a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) B) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (C,b)
+         (C == (unsigned long) b) +
+         (C == (unsigned int) b) +
+         (C == (unsigned short) b) +
+         (C == (unsigned char) b) +
+         ((long) C == b) +
+         ((int) C == b) +
+         ((short) C == b) +
+         ((signed char) C == b) +
+         ((long) C == (unsigned long) b) +
+         ((int) C == (unsigned int) b) +
+         ((short) C == (unsigned short) b) +
+         ((signed char) C == (unsigned char) b) +
+         (C < (unsigned long) b) +
+         (C < (unsigned int) b) +
+         (C < (unsigned short) b) +
+         (C < (unsigned char) b) +
+         ((long) C < b) +
+         ((int) C < b) +
+         ((short) C < b) +
+         ((signed char) C < b) +
+         ((long) C < (unsigned long) b) +
+         ((int) C < (unsigned int) b) +
+         ((short) C < (unsigned short) b) +
+         ((signed char) C < (unsigned char) b) +
+
+         // (a,C)
+         (a == (unsigned long) C) +
+         (a == (unsigned int) C) +
+         (a == (unsigned short) C) +
+         (a == (unsigned char) C) +
+         ((long) a == C) +
+         ((int) a == C) +
+         ((short) a == C) +
+         ((signed char) a == C) +
+         ((long) a == (unsigned long) C) +
+         ((int) a == (unsigned int) C) +
+         ((short) a == (unsigned short) C) +
+         ((signed char) a == (unsigned char) C) +
+         (a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) C) +
+         (a < (unsigned short) C) +
+         (a < (unsigned char) C) +
+         ((long) a < C) +
+         ((int) a < C) +
+         ((short) a < C) +
+         ((signed char) a < C) +
+         ((long) a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) C) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (0x80000,b)
+         (0x80000 == (unsigned long) b) +
+         (0x80000 == (unsigned int) b) +
+         (0x80000 == (unsigned short) b) +
+         (0x80000 == (unsigned char) b) +
+         ((long) 0x80000 == b) +
+         ((int) 0x80000 == b) +
+         ((short) 0x80000 == b) +
+         ((signed char) 0x80000 == b) +
+         ((long) 0x80000 == (unsigned long) b) +
+         ((int) 0x80000 == (unsigned int) b) +
+         ((short) 0x80000 == (unsigned short) b) +
+         ((signed char) 0x80000 == (unsigned char) b) +
+         (0x80000 < (unsigned long) b) +
+         (0x80000 < (unsigned int) b) +
+         (0x80000 < (unsigned short) b) +
+         (0x80000 < (unsigned char) b) +
+         ((long) 0x80000 < b) +
+         ((int) 0x80000 < b) +
+         ((short) 0x80000 < b) +
+         ((signed char) 0x80000 < b) +
+         ((long) 0x80000 < (unsigned long) b) +
+         ((int) 0x80000 < (unsigned int) b) +
+         ((short) 0x80000 < (unsigned short) b) +
+         ((signed char) 0x80000 < (unsigned char) b) +
+
+         // (a,0x80000)
+         (a == (unsigned long) 0x80000) +
+         (a == (unsigned int) 0x80000) +
+         (a == (unsigned short) 0x80000) +
+         (a == (unsigned char) 0x80000) +
+         ((long) a == 0x80000) +
+         ((int) a == 0x80000) +
+         ((short) a == 0x80000) +
+         ((signed char) a == 0x80000) +
+         ((long) a == (unsigned long) 0x80000) +
+         ((int) a == (unsigned int) 0x80000) +
+         ((short) a == (unsigned short) 0x80000) +
+         ((signed char) a == (unsigned char) 0x80000) +
+         (a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) 0x80000) +
+         (a < (unsigned short) 0x80000) +
+         (a < (unsigned char) 0x80000) +
+         ((long) a < 0x80000) +
+         ((int) a < 0x80000) +
+         ((short) a < 0x80000) +
+         ((signed char) a < 0x80000) +
+         ((long) a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) 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}}
+
+         10
+    ;
 }
 
 int equal(char *a, const char *b) {
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 2a29634..e38b6b3 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -1,15 +1,195 @@
-// RUN: clang-cc -fsyntax-only -pedantic -verify -Wsign-compare %s
+// Force x86-64 because some of our heuristics are actually based
+// on integer sizes.
+
+// RUN: clang-cc -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare %s
 
 int test0(long a, unsigned long b) {
-  enum Enum {B};
-  return (a == B) +        // expected-warning {{comparison of integers of different signs}}
-         ((int)a == B) +   // expected-warning {{comparison of integers of different signs}}
-         ((short)a == B) + // expected-warning {{comparison of integers of different signs}}
-         (a == (unsigned int) B) +  // expected-warning {{comparison of integers of different signs}}
-         (a == (unsigned short) B); // expected-warning {{comparison of integers of different signs}}         
+  enum EnumA {A};
+  enum EnumB {B};
+  enum EnumC {C = 0x10000};
+  return
+         // (a,b)
+         (a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a == (unsigned int) b) +
+         (a == (unsigned short) b) +
+         (a == (unsigned char) b) +
+         ((long) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a == (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a == (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a == (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a == (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) b) +
+         (a < (unsigned short) b) +
+         (a < (unsigned char) b) +
+         ((long) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a < (unsigned long) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
 
-  // Should be able to prove all of these are non-negative.
-  return (b == (long) B) +
-         (b == (int) B) +
-         (b == (short) B);
+         // (A,b)
+         (A == (unsigned long) b) +
+         (A == (unsigned int) b) +
+         (A == (unsigned short) b) +
+         (A == (unsigned char) b) +
+         ((long) A == b) +
+         ((int) A == b) +
+         ((short) A == b) +
+         ((signed char) A == b) +
+         ((long) A == (unsigned long) b) +
+         ((int) A == (unsigned int) b) +
+         ((short) A == (unsigned short) b) +
+         ((signed char) A == (unsigned char) b) +
+         (A < (unsigned long) b) +
+         (A < (unsigned int) b) +
+         (A < (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         (A < (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) A < b) +
+         ((int) A < b) +
+         ((short) A < b) +
+         ((signed char) A < b) +
+         ((long) A < (unsigned long) b) +
+         ((int) A < (unsigned int) b) +
+         ((short) A < (unsigned short) b) +
+         ((signed char) A < (unsigned char) b) +
+
+         // (a,B)
+         (a == (unsigned long) B) +
+         (a == (unsigned int) B) +
+         (a == (unsigned short) B) +
+         (a == (unsigned char) B) +
+         ((long) a == B) +
+         ((int) a == B) +
+         ((short) a == B) +
+         ((signed char) a == B) +
+         ((long) a == (unsigned long) B) +
+         ((int) a == (unsigned int) B) +
+         ((short) a == (unsigned short) B) +
+         ((signed char) a == (unsigned char) B) +
+         (a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) B) +
+         (a < (unsigned short) B) +
+         (a < (unsigned char) B) +
+         ((long) a < B) +
+         ((int) a < B) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < B) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < B) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a < (unsigned long) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) B) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) B) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (C,b)
+         (C == (unsigned long) b) +
+         (C == (unsigned int) b) +
+         (C == (unsigned short) b) +
+         (C == (unsigned char) b) +
+         ((long) C == b) +
+         ((int) C == b) +
+         ((short) C == b) +
+         ((signed char) C == b) +
+         ((long) C == (unsigned long) b) +
+         ((int) C == (unsigned int) b) +
+         ((short) C == (unsigned short) b) +
+         ((signed char) C == (unsigned char) b) +
+         (C < (unsigned long) b) +
+         (C < (unsigned int) b) +
+         (C < (unsigned short) b) +  // expected-warning {{comparison of integers of different signs}}
+         (C < (unsigned char) b) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) C < b) +
+         ((int) C < b) +
+         ((short) C < b) +
+         ((signed char) C < b) +
+         ((long) C < (unsigned long) b) +
+         ((int) C < (unsigned int) b) +
+         ((short) C < (unsigned short) b) +
+         ((signed char) C < (unsigned char) b) +
+
+         // (a,C)
+         (a == (unsigned long) C) +
+         (a == (unsigned int) C) +
+         (a == (unsigned short) C) +
+         (a == (unsigned char) C) +
+         ((long) a == C) +
+         ((int) a == C) +
+         ((short) a == C) +
+         ((signed char) a == C) +
+         ((long) a == (unsigned long) C) +
+         ((int) a == (unsigned int) C) +
+         ((short) a == (unsigned short) C) +
+         ((signed char) a == (unsigned char) C) +
+         (a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) C) +
+         (a < (unsigned short) C) +
+         (a < (unsigned char) C) +
+         ((long) a < C) +
+         ((int) a < C) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < C) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < C) +  // expected-warning {{comparison of integers of different signs}}
+         ((long) a < (unsigned long) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((short) a < (unsigned short) C) +  // expected-warning {{comparison of integers of different signs}}
+         ((signed char) a < (unsigned char) C) +  // expected-warning {{comparison of integers of different signs}}
+
+         // (0x80000,b)
+         (0x80000 == (unsigned long) b) +
+         (0x80000 == (unsigned int) b) +
+         (0x80000 == (unsigned short) b) +
+         (0x80000 == (unsigned char) b) +
+         ((long) 0x80000 == b) +
+         ((int) 0x80000 == b) +
+         ((short) 0x80000 == b) +
+         ((signed char) 0x80000 == b) +
+         ((long) 0x80000 == (unsigned long) b) +
+         ((int) 0x80000 == (unsigned int) b) +
+         ((short) 0x80000 == (unsigned short) b) +
+         ((signed char) 0x80000 == (unsigned char) b) +
+         (0x80000 < (unsigned long) b) +
+         (0x80000 < (unsigned int) b) +
+         (0x80000 < (unsigned short) b) +
+         (0x80000 < (unsigned char) b) +
+         ((long) 0x80000 < b) +
+         ((int) 0x80000 < b) +
+         ((short) 0x80000 < b) +
+         ((signed char) 0x80000 < b) +
+         ((long) 0x80000 < (unsigned long) b) +
+         ((int) 0x80000 < (unsigned int) b) +
+         ((short) 0x80000 < (unsigned short) b) +
+         ((signed char) 0x80000 < (unsigned char) b) +
+
+         // (a,0x80000)
+         (a == (unsigned long) 0x80000) +
+         (a == (unsigned int) 0x80000) +
+         (a == (unsigned short) 0x80000) +
+         (a == (unsigned char) 0x80000) +
+         ((long) a == 0x80000) +
+         ((int) a == 0x80000) +
+         ((short) a == 0x80000) +
+         ((signed char) a == 0x80000) +
+         ((long) a == (unsigned long) 0x80000) +
+         ((int) a == (unsigned int) 0x80000) +
+         ((short) a == (unsigned short) 0x80000) +
+         ((signed char) a == (unsigned char) 0x80000) +
+         (a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         (a < (unsigned int) 0x80000) +
+         (a < (unsigned short) 0x80000) +
+         (a < (unsigned char) 0x80000) +
+         ((long) a < 0x80000) +
+         ((int) a < 0x80000) +
+         ((short) a < 0x80000) +
+         ((signed char) a < 0x80000) +
+         ((long) a < (unsigned long) 0x80000) +  // expected-warning {{comparison of integers of different signs}}
+         ((int) a < (unsigned int) 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}}
+
+         10
+    ;
 }