diff options
-rw-r--r-- | include/clang/AST/Expr.h | 5 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 5 | ||||
-rw-r--r-- | test/SemaObjCXX/blocks.mm | 6 |
5 files changed, 18 insertions, 1 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 48bd1e8041..610cbd8c30 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1575,7 +1575,10 @@ public: /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c /// pointer - CK_AnyPointerToObjCPointerCast + CK_AnyPointerToObjCPointerCast, + /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block + /// pointer + CK_AnyPointerToBlockPointerCast }; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index e8758d814d..6eca6a1fa2 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -560,6 +560,8 @@ const char *CastExpr::getCastKindName() const { return "MemberPointerToBoolean"; case CastExpr::CK_AnyPointerToObjCPointerCast: return "AnyPointerToObjCPointerCast"; + case CastExpr::CK_AnyPointerToBlockPointerCast: + return "AnyPointerToBlockPointerCast"; } assert(0 && "Unhandled cast kind!"); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 6f65638236..afb7a798ef 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -809,6 +809,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { break; case CastExpr::CK_AnyPointerToObjCPointerCast: + case CastExpr::CK_AnyPointerToBlockPointerCast: case CastExpr::CK_BitCast: { Value *Src = Visit(const_cast<Expr*>(E)); return Builder.CreateBitCast(Src, ConvertType(DestTy)); diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 857241d714..814af9080d 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -545,6 +545,11 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, Kind = CastExpr::CK_AnyPointerToObjCPointerCast; return TC_Success; } + else if (CStyle && DestType->isBlockPointerType()) { + // allow c-style cast of void * to block pointers. + Kind = CastExpr::CK_AnyPointerToBlockPointerCast; + return TC_Success; + } } } diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm index e3304a41b7..04eb5217e5 100644 --- a/test/SemaObjCXX/blocks.mm +++ b/test/SemaObjCXX/blocks.mm @@ -44,3 +44,9 @@ namespace N { foo(N::X()); // okay } @end + +typedef signed char BOOL; +void foo6(void *block) { + void (^vb)(id obj, int idx, BOOL *stop) = (void (^)(id, int, BOOL *))block; + BOOL (^bb)(id obj, int idx, BOOL *stop) = (BOOL (^)(id, int, BOOL *))block; +} |