// 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;
else if (ToType->isBooleanType() &&
(FromType->isArithmeticType() ||
FromType->isEnumeralType() ||
- FromType->isPointerType())) {
+ FromType->isPointerType() ||
+ FromType->isBlockPointerType())) {
SCS.Second = ICK_Boolean_Conversion;
FromType = Context.BoolTy;
} else {
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;
// 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;
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).
--- /dev/null
+// 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) { }
+}