[cfe-commits] r107905 - in /cfe/trunk: lib/Sema/SemaCXXCast.cpp test/SemaCXX/blocks-1.cpp

Douglas Gregor dgregor at apple.com
Thu Jul 8 13:27:33 PDT 2010


Author: dgregor
Date: Thu Jul  8 15:27:32 2010
New Revision: 107905

URL: http://llvm.org/viewvc/llvm-project?rev=107905&view=rev
Log:
Allow C-style casts and reinterpret_casts between block pointers and
either integer values or other pointers. Fixes <rdar://problem/8134521>.

Modified:
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/test/SemaCXX/blocks-1.cpp

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=107905&r1=107904&r2=107905&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Thu Jul  8 15:27:32 2010
@@ -233,6 +233,15 @@
     T2 = T2MPType->getPointeeType();
     return true;
   }
+  
+  const BlockPointerType *T1BPType = T1->getAs<BlockPointerType>(),
+                         *T2BPType = T2->getAs<BlockPointerType>();
+  if (T1BPType && T2BPType) {
+    T1 = T1BPType->getPointeeType();
+    T2 = T2BPType->getPointeeType();
+    return true;
+  }
+  
   return false;
 }
 
@@ -246,9 +255,11 @@
   // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since
   // the rules are non-trivial. So first we construct Tcv *...cv* as described
   // in C++ 5.2.11p8.
-  assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType()) &&
+  assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() ||
+          SrcType->isBlockPointerType()) &&
          "Source type is not pointer or pointer to member.");
-  assert((DestType->isAnyPointerType() || DestType->isMemberPointerType()) &&
+  assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() ||
+          DestType->isBlockPointerType()) &&
          "Destination type is not pointer or pointer to member.");
 
   QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), 
@@ -265,7 +276,8 @@
     Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
     cv2.push_back(DestQuals);
   }
-  assert(cv1.size() > 0 && "Must have at least one pointer level.");
+  if (cv1.empty())
+    return false;
 
   // Construct void pointers with those qualifiers (in reverse order of
   // unwrapping, of course).
@@ -1128,8 +1140,10 @@
     return TC_Failed;
   }
   
-  bool destIsPtr = DestType->isAnyPointerType();
-  bool srcIsPtr = SrcType->isAnyPointerType();
+  bool destIsPtr = DestType->isAnyPointerType() ||
+                   DestType->isBlockPointerType();
+  bool srcIsPtr = SrcType->isAnyPointerType() ||
+                  SrcType->isBlockPointerType();
   if (!destIsPtr && !srcIsPtr) {
     // Except for std::nullptr_t->integer and lvalue->reference, which are
     // handled above, at least one of the two arguments must be a pointer.
@@ -1180,11 +1194,19 @@
     msg = diag::err_bad_cxx_cast_const_away;
     return TC_Failed;
   }
+  
+  // Cannot convert between block pointers and Objective-C object pointers.
+  if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) ||
+      (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType()))
+    return TC_NotApplicable;
+
+  // Any pointer can be cast to an Objective-C pointer type with a C-style
+  // cast.
   if (CStyle && DestType->isObjCObjectPointerType()) {
     Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
     return TC_Success;
   }
-  
+    
   // Not casting away constness, so the only remaining check is for compatible
   // pointer categories.
   Kind = CastExpr::CK_BitCast;
@@ -1213,7 +1235,7 @@
       Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange;
     return TC_Success;
   }
-
+  
   // C++ 5.2.10p7: A pointer to an object can be explicitly converted to
   //   a pointer to an object of different type.
   // Void pointers are not specified, but supported by every compiler out there.

Modified: cfe/trunk/test/SemaCXX/blocks-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/blocks-1.cpp?rev=107905&r1=107904&r2=107905&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/blocks-1.cpp (original)
+++ cfe/trunk/test/SemaCXX/blocks-1.cpp Thu Jul  8 15:27:32 2010
@@ -33,3 +33,13 @@
     
     return 0;
 }
+
+namespace rdar8134521 {
+  void foo() {
+    int (^P)(int) = reinterpret_cast<int(^)(int)>(1);
+    P = (int(^)(int))(1);
+    
+    P = reinterpret_cast<int(^)(int)>((void*)1);
+    P = (int(^)(int))((void*)1);
+  }
+}





More information about the cfe-commits mailing list