]> granicus.if.org Git - clang/commitdiff
Cases like this:
authorChris Lattner <sabre@nondot.org>
Sun, 26 Aug 2007 01:10:14 +0000 (01:10 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 26 Aug 2007 01:10:14 +0000 (01:10 +0000)
  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

Sema/SemaExpr.cpp
test/Sema/compare.c [new file with mode: 0644]

index 7666ad0474d4cbce7c6858ac5741ca0be8ffc5d4..e26f5c1f3d54dc3ab81ee3fa2cdd610f537c8840 100644 (file)
@@ -1068,33 +1068,35 @@ inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
   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 @@ inline QualType Sema::CheckEqualityOperands( // C99 6.5.9
   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);
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
new file mode 100644 (file)
index 0000000..0aeeb30
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang -parse-ast-check %s
+
+int test(char *C) { // nothing here should warn.
+  return C != ((void*)0);
+  return C != (void*)0;
+  return C != 0;
+}
+