]> granicus.if.org Git - clang/commitdiff
Implement PR4175, catching some questionable comparisons. Patch by
authorChris Lattner <sabre@nondot.org>
Tue, 30 Jun 2009 06:24:05 +0000 (06:24 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 30 Jun 2009 06:24:05 +0000 (06:24 +0000)
David Majnemer!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74513 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/Sema/compare.c

index 652f7430f0c60bb507c9cf3a600260345e4032be..8a532d62a71e0e71b53f6fcadd0aaa2112ed1162 100644 (file)
@@ -1213,6 +1213,10 @@ def err_typecheck_sub_ptr_object : Error<
   "subtraction of pointer %0 requires pointee to be a complete object type">;
 def err_typecheck_sub_ptr_compatible : Error<
   "%0 and %1 are not pointers to compatible types">;
+def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
+  "ordered comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
+  "ordered comparison of function pointers (%0 and %1)">;
 def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
   "comparison between pointer and integer (%0 and %1)">;
 def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
index 28617bbfeac53e0bcb61ef58c0bb70845ca8678c..1df3d4f722f6ec91e706ed286a5e3d40b7c4c30d 100644 (file)
@@ -4028,6 +4028,17 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
     QualType RCanPointeeTy =
       Context.getCanonicalType(rType->getAsPointerType()->getPointeeType());
 
+    if (rType->isFunctionPointerType() || lType->isFunctionPointerType()) {
+      if (isRelational) {
+        Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      }
+    }
+    if (((!LHSIsNull || isRelational) && LCanPointeeTy->isVoidType()) !=
+        ((!RHSIsNull || isRelational) && RCanPointeeTy->isVoidType())) {
+      Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    }
     // Simple check: if the pointee types are identical, we're done.
     if (LCanPointeeTy == RCanPointeeTy)
       return ResultTy;
@@ -4140,7 +4151,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
   }
   if ((lType->isPointerType() || lType->isObjCQualifiedIdType()) &&
        rType->isIntegerType()) {
-    if (!RHSIsNull)
+    if (isRelational)
+      Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    else if (!RHSIsNull)
       Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     ImpCastExprToType(rex, lType); // promote the integer to pointer
@@ -4148,7 +4162,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
   }
   if (lType->isIntegerType() &&
       (rType->isPointerType() || rType->isObjCQualifiedIdType())) {
-    if (!LHSIsNull)
+    if (isRelational)
+      Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer)
+        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+    else if (!LHSIsNull)
       Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     ImpCastExprToType(lex, rType); // promote the integer to pointer
index 4b44bf5b96a0779ac2cadd0140d923c95b5a8dba..51f77317385ca1674c9155dd5bd1852df49924d9 100644 (file)
@@ -15,3 +15,17 @@ int arrays(char (*a)[5], char(*b)[10], char(*c)[5]) {
   int d = (a == c);
   return a == b; // expected-warning {{comparison of distinct pointer types}}
 }
+
+int pointers(int *a)
+{
+  return a > 0; // expected-warning {{ordered comparison between pointer and integer}}
+  return a > (void *)0; // expected-warning {{comparison of distinct pointer types}}
+}
+
+int function_pointers(int (*a)(int), int (*b)(int))
+{
+  return a > b; // expected-warning {{ordered comparison of function pointers}}
+  return function_pointers > function_pointers; // expected-warning {{ordered comparison of function pointers}}
+  return a == (void *) 0;
+  return a == (void *) 1; // expected-warning {{comparison of distinct pointer types}}
+}