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

Douglas Gregor dgregor at apple.com
Tue Jun 15 14:38:40 PDT 2010


Author: dgregor
Date: Tue Jun 15 16:38:40 2010
New Revision: 106050

URL: http://llvm.org/viewvc/llvm-project?rev=106050&view=rev
Log:
Update equality and relationship comparisons of pointers to reflect
C++ semantics, eliminating an extension diagnostic that doesn't match
C++ semantics (ordered comparison with NULL) and tightening some
extwarns to errors in C++ to match GCC and maintain conformance in
SFINAE contexts. Fixes <rdar://problem/7941392>.

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

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=106050&r1=106049&r2=106050&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 15 16:38:40 2010
@@ -2087,8 +2087,12 @@
   "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 err_typecheck_comparison_of_fptr_to_void : Error<
+  "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 err_typecheck_comparison_of_pointer_integer : Error<
+  "comparison between pointer and integer (%0 and %1)">;
 def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
   "comparison of distinct pointer types (%0 and %1)">;
 def ext_typecheck_cond_incompatible_operands : ExtWarn<

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=106050&r1=106049&r2=106050&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 15 16:38:40 2010
@@ -5408,9 +5408,8 @@
   bool RHSIsNull = rex->isNullPointerConstant(Context,
                                               Expr::NPC_ValueDependentIsNull);
 
-  // All of the following pointer related warnings are GCC extensions, except
-  // when handling null pointer constants. One day, we can consider making them
-  // errors (when -pedantic-errors is enabled).
+  // All of the following pointer-related warnings are GCC extensions, except
+  // when handling null pointer constants. 
   if (lType->isPointerType() && rType->isPointerType()) { // C99 6.5.8p2
     QualType LCanPointeeTy =
       Context.getCanonicalType(lType->getAs<PointerType>()->getPointeeType());
@@ -5424,10 +5423,19 @@
           (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
         // Valid unless comparison between non-null pointer and function pointer
         // This is a gcc extension compatibility comparison.
+        // In a SFINAE context, we treat this as a hard error to maintain
+        // conformance with the C++ standard.
         if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
             && !LHSIsNull && !RHSIsNull) {
-          Diag(Loc, diag::ext_typecheck_comparison_of_fptr_to_void)
+          Diag(Loc, 
+               isSFINAEContext()? 
+                   diag::err_typecheck_comparison_of_fptr_to_void
+                 : diag::ext_typecheck_comparison_of_fptr_to_void)
             << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+          
+          if (isSFINAEContext())
+            return QualType();
+          
           ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
           return ResultTy;
         }
@@ -5591,40 +5599,36 @@
       return ResultTy;
     }
   }
-  if (lType->isAnyPointerType() && rType->isIntegerType()) {
+  if ((lType->isAnyPointerType() && rType->isIntegerType()) ||
+      (lType->isIntegerType() && rType->isAnyPointerType())) {
     unsigned DiagID = 0;
-    if (RHSIsNull) {
-      if (isRelational)
+    bool isError = false;
+    if ((LHSIsNull && lType->isIntegerType()) ||
+        (RHSIsNull && rType->isIntegerType())) {
+      if (isRelational && !getLangOptions().CPlusPlus)
         DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
-    } else if (isRelational)
+    } else if (isRelational && !getLangOptions().CPlusPlus)
       DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
-    else
+    else if (getLangOptions().CPlusPlus) {
+      DiagID = diag::err_typecheck_comparison_of_pointer_integer;
+      isError = true;
+    } else
       DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
 
     if (DiagID) {
       Diag(Loc, DiagID)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+      if (isError)
+        return QualType();
     }
-    ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
-    return ResultTy;
-  }
-  if (lType->isIntegerType() && rType->isAnyPointerType()) {
-    unsigned DiagID = 0;
-    if (LHSIsNull) {
-      if (isRelational)
-        DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
-    } else if (isRelational)
-      DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
+    
+    if (lType->isIntegerType())
+      ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
     else
-      DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
-
-    if (DiagID) {
-      Diag(Loc, DiagID)
-        << lType << rType << lex->getSourceRange() << rex->getSourceRange();
-    }
-    ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
     return ResultTy;
   }
+  
   // Handle block pointers.
   if (!isRelational && RHSIsNull
       && lType->isBlockPointerType() && rType->isIntegerType()) {

Modified: cfe/trunk/test/SemaCXX/compare.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/compare.cpp?rev=106050&r1=106049&r2=106050&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/compare.cpp (original)
+++ cfe/trunk/test/SemaCXX/compare.cpp Tue Jun 15 16:38:40 2010
@@ -198,3 +198,11 @@
   enum en { zero };
   return i > zero;
 }
+
+enum E { e };
+void test2(int i, void *vp) {
+  if (test1 == vp) { } // expected-warning{{equality comparison between function pointer and void pointer}}
+  if (test1 == e) { } // expected-error{{comparison between pointer and integer}}
+  if (vp < 0) { }
+  if (test1 < e) { } // expected-error{{comparison between pointer and integer}}
+}





More information about the cfe-commits mailing list