]> granicus.if.org Git - clang/commitdiff
Add some block-pointer conversions in C++
authorDouglas Gregor <dgregor@apple.com>
Tue, 23 Dec 2008 00:53:59 +0000 (00:53 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 23 Dec 2008 00:53:59 +0000 (00:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61359 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaObjC/blocks.m
test/SemaObjCXX/blocks.mm [new file with mode: 0644]

index 8463c5d34ba5e6d81b2641fd6eb6c6de32425f6a..b2130e42f886ccf565f1da2d3d28db088fb42189 100644 (file)
@@ -135,7 +135,7 @@ bool StandardConversionSequence::isPointerConversionToBool() const
   // check for their presence as well as checking whether FromType is
   // a pointer.
   if (ToType->isBooleanType() &&
-      (FromType->isPointerType() ||
+      (FromType->isPointerType() || FromType->isBlockPointerType() ||
        First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer))
     return true;
 
@@ -547,7 +547,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
   else if (ToType->isBooleanType() &&
            (FromType->isArithmeticType() ||
             FromType->isEnumeralType() ||
-            FromType->isPointerType())) {
+            FromType->isPointerType() ||
+            FromType->isBlockPointerType())) {
     SCS.Second = ICK_Boolean_Conversion;
     FromType = Context.BoolTy;
   } else {
@@ -857,25 +858,33 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
     return true;
   }
 
+  // Beyond this point, both types need to be pointers or block pointers.
+  QualType ToPointeeType;
   const PointerType* ToTypePtr = ToType->getAsPointerType();
-  if (!ToTypePtr)
+  if (ToTypePtr)
+    ToPointeeType = ToTypePtr->getPointeeType();
+  else if (const BlockPointerType *ToBlockPtr = ToType->getAsBlockPointerType())
+    ToPointeeType = ToBlockPtr->getPointeeType();
+  else
     return false;
 
-  // Beyond this point, both types need to be pointers.
+  QualType FromPointeeType;
   const PointerType *FromTypePtr = FromType->getAsPointerType();
-  if (!FromTypePtr)
+  if (FromTypePtr)
+    FromPointeeType = FromTypePtr->getPointeeType();
+  else if (const BlockPointerType *FromBlockPtr 
+             = FromType->getAsBlockPointerType())
+    FromPointeeType = FromBlockPtr->getPointeeType();
+  else
     return false;
 
-  QualType FromPointeeType = FromTypePtr->getPointeeType();
-  QualType ToPointeeType = ToTypePtr->getPointeeType();
-
   // Objective C++: We're able to convert from a pointer to an
   // interface to a pointer to a different interface.
   const ObjCInterfaceType* FromIface = FromPointeeType->getAsObjCInterfaceType();
   const ObjCInterfaceType* ToIface = ToPointeeType->getAsObjCInterfaceType();
   if (FromIface && ToIface && 
       Context.canAssignObjCInterfaces(ToIface, FromIface)) {
-    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, 
+    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
                                                        ToPointeeType,
                                                        ToType, Context);
     return true;
@@ -887,7 +896,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
     // interfaces, which is permitted. However, we're going to
     // complain about it.
     IncompatibleObjC = true;
-    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, 
+    ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
                                                        ToPointeeType,
                                                        ToType, Context);
     return true;
@@ -924,7 +933,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
     return true;
   }
 
-  // If we have pointers to functions, check whether the only
+  // If we have pointers to functions or blocks, check whether the only
   // differences in the argument and result types are in Objective-C
   // pointer conversions. If so, we permit the conversion (but
   // complain about it).
index dd8380aea928d215d5476611406850c6338f774e..8e72be6e37ed5c89008ad1700b9d5dfcc061b0f7 100644 (file)
@@ -20,3 +20,7 @@ void bar4(id(^)());
 void foo4(id (^objectCreationBlock)(int)) {
     return bar4(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)()'}}
 }
+
+void foo5(id (^x)(int)) {
+  if (x) { }
+}
diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
new file mode 100644 (file)
index 0000000..8aee152
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: clang -fsyntax-only -verify -fblocks %s
+@protocol NSObject;
+
+void bar(id(^)(void));
+void foo(id <NSObject>(^objectCreationBlock)(void)) {
+    return bar(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id (^)(void)', expected 'id<NSObject> (^)(void)'}}
+}
+
+void bar2(id(*)(void));
+void foo2(id <NSObject>(*objectCreationBlock)(void)) {
+    return bar2(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id (*)(void)', expected 'id<NSObject> (*)(void)'}}
+}
+
+void bar3(id(*)());
+void foo3(id (*objectCreationBlock)(int)) {
+    return bar3(objectCreationBlock); // expected-error{{incompatible type passing 'id (*)(int)', expected 'id (*)(void)'}}
+}
+
+void bar4(id(^)());
+void foo4(id (^objectCreationBlock)(int)) {
+    return bar4(objectCreationBlock); // expected-error{{incompatible type passing 'id (^)(int)', expected 'id (^)(void)'}}
+}
+
+void foo5(id (^x)(int)) {
+  if (x) { }
+}