[cfe-commits] r79793 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/Sema/compare.c

Eli Friedman eli.friedman at gmail.com
Sat Aug 22 17:27:47 PDT 2009


Author: efriedma
Date: Sat Aug 22 19:27:47 2009
New Revision: 79793

URL: http://llvm.org/viewvc/llvm-project?rev=79793&view=rev
Log:
Catch a few more cases of illegal comparisons.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/compare.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=79793&r1=79792&r2=79793&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Aug 22 19:27:47 2009
@@ -1352,6 +1352,8 @@
   "ordered comparison between pointer and zero (%0 and %1) is an extension">;
 def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
   "ordered comparison of function pointers (%0 and %1)">;
+def ext_typecheck_comparison_of_fptr_to_void : Extension<
+  "equality comparison between function pointer and void pointer (%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<

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=79793&r1=79792&r2=79793&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Aug 22 19:27:47 2009
@@ -4237,28 +4237,10 @@
     QualType RCanPointeeTy =
       Context.getCanonicalType(rType->getAs<PointerType>()->getPointeeType());
 
-    if (isRelational) {
-      if (lType->isFunctionPointerType() || rType->isFunctionPointerType()) {
-        Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
-          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
-      }
-      if (LCanPointeeTy->isVoidType() != RCanPointeeTy->isVoidType()) {
-        Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
-          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
-      }
-    } else {
-      if (lType->isFunctionPointerType() != rType->isFunctionPointerType()) {
-        if (!LHSIsNull && !RHSIsNull)
-          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;
-
     if (getLangOptions().CPlusPlus) {
+      if (LCanPointeeTy == RCanPointeeTy)
+        return ResultTy;
+
       // C++ [expr.rel]p2:
       //   [...] Pointer conversions (4.10) and qualification
       //   conversions (4.4) are performed on pointer operands (or on
@@ -4278,15 +4260,29 @@
       ImpCastExprToType(rex, T);
       return ResultTy;
     }
-
-    if (!LHSIsNull && !RHSIsNull &&                       // C99 6.5.9p2
-        !LCanPointeeTy->isVoidType() && !RCanPointeeTy->isVoidType() &&
-        !Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
-                                    RCanPointeeTy.getUnqualifiedType())) {
+    // C99 6.5.9p2 and C99 6.5.8p2
+    if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
+                                   RCanPointeeTy.getUnqualifiedType())) {
+      // Valid unless a relational comparison of function pointers
+      if (isRelational && LCanPointeeTy->isFunctionType()) {
+        Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      }
+    } else if (!isRelational &&
+               (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
+      // Valid unless comparison between non-null pointer and function pointer
+      if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
+          && !LHSIsNull && !RHSIsNull) {
+        Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
+          << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      }
+    } else {
+      // Invalid
       Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
-    ImpCastExprToType(rex, lType); // promote the pointer to pointer
+    if (LCanPointeeTy != RCanPointeeTy)
+      ImpCastExprToType(rex, lType); // promote the pointer to pointer
     return ResultTy;
   }
   // C++ allows comparison of pointers with null pointer constants.

Modified: cfe/trunk/test/Sema/compare.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/compare.c?rev=79793&r1=79792&r2=79793&view=diff

==============================================================================
--- cfe/trunk/test/Sema/compare.c (original)
+++ cfe/trunk/test/Sema/compare.c Sat Aug 22 19:27:47 2009
@@ -24,13 +24,15 @@
   return a > (void *)0; // expected-warning {{comparison of distinct pointer types}}
 }
 
-int function_pointers(int (*a)(int), int (*b)(int)) {
+int function_pointers(int (*a)(int), int (*b)(int), void (*c)(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 > c; // expected-warning {{comparison of distinct pointer types}}
   return a == (void *) 0;
-  return a == (void *) 1; // expected-warning {{comparison of distinct pointer types}}
+  return a == (void *) 1; // expected-warning {{equality comparison between function pointer and void pointer}}
 }
 
-int void_pointers(void *foo) {
-  return foo == NULL;
+int void_pointers(void* foo) {
+  return foo == (void*) 0;
+  return foo == (void*) 1;
 }





More information about the cfe-commits mailing list