Cases like this:
  char *C;
  C != ((void*)0);

Should not warn about incompatible pointer types.  Also, make sure to
insert an implicit conversion even if the operand is null.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41408 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 7666ad0..e26f5c1 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -1068,33 +1068,35 @@
   if (lType->isRealType() && rType->isRealType())
     return Context.IntTy;
   
+  bool LHSIsNull = lex->isNullPointerConstant(Context);
+  bool RHSIsNull = rex->isNullPointerConstant(Context);
+  
   // All of the following pointer related warnings are GCC extensions. One
   // day, we can consider making them errors (when -pedantic-errors is enabled).
   if (lType->isPointerType() && rType->isPointerType()) {
-    if (!Type::pointerTypesAreCompatible(lType, rType)) {
+    if (!LHSIsNull && !RHSIsNull &&
+        !Type::pointerTypesAreCompatible(lType, rType)) {
       Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
-      promoteExprToType(rex, lType); // promote the pointer to pointer
     }
+    promoteExprToType(rex, lType); // promote the pointer to pointer
     return Context.IntTy;
   }
   if (lType->isPointerType() && rType->isIntegerType()) {
-    if (!rex->isNullPointerConstant(Context)) {
+    if (!RHSIsNull)
       Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
-      promoteExprToType(rex, lType); // promote the integer to pointer
-    }
+    promoteExprToType(rex, lType); // promote the integer to pointer
     return Context.IntTy;
   }
   if (lType->isIntegerType() && rType->isPointerType()) {
-    if (!lex->isNullPointerConstant(Context)) {
+    if (!LHSIsNull)
       Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
-      promoteExprToType(lex, rType); // promote the integer to pointer
-    }
+    promoteExprToType(lex, rType); // promote the integer to pointer
     return Context.IntTy;
   }
   InvalidOperands(loc, lex, rex);
@@ -1117,33 +1119,37 @@
   if (lType->isArithmeticType() && rType->isArithmeticType())
     return Context.IntTy;
     
+  bool LHSIsNull = lex->isNullPointerConstant(Context);
+  bool RHSIsNull = rex->isNullPointerConstant(Context);
+
   // All of the following pointer related warnings are GCC extensions. One
   // day, we can consider making them errors (when -pedantic-errors is enabled).
   if (lType->isPointerType() && rType->isPointerType()) {
-    if (!Type::pointerTypesAreCompatible(lType, rType)) {
+    if (!LHSIsNull && !RHSIsNull &&
+        !Type::pointerTypesAreCompatible(lType, rType)) {
       Diag(loc, diag::ext_typecheck_comparison_of_distinct_pointers,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
-      promoteExprToType(rex, lType); // promote the pointer to pointer
     }
+    promoteExprToType(rex, lType); // promote the pointer to pointer
     return Context.IntTy;
   }
   if (lType->isPointerType() && rType->isIntegerType()) {
-    if (!rex->isNullPointerConstant(Context)) {
+    if (!RHSIsNull) {
       Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
-      promoteExprToType(rex, lType); // promote the integer to pointer
     }
+    promoteExprToType(rex, lType); // promote the integer to pointer
     return Context.IntTy;
   }
   if (lType->isIntegerType() && rType->isPointerType()) {
-    if (!lex->isNullPointerConstant(Context)) {
+    if (!LHSIsNull) {
       Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer,
            lType.getAsString(), rType.getAsString(),
            lex->getSourceRange(), rex->getSourceRange());
-      promoteExprToType(lex, rType); // promote the integer to pointer
     }
+    promoteExprToType(lex, rType); // promote the integer to pointer
     return Context.IntTy;
   }
   InvalidOperands(loc, lex, rex);