From: Steve Naroff Date: Wed, 10 Dec 2008 17:49:55 +0000 (+0000) Subject: Fix Bogus block type compatibility warning. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c0febd58f5cbf4a93fd12f461863564dba0af76d;p=clang Fix Bogus block type compatibility warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60842 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 35647cf02a..ba61332a44 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1920,7 +1920,13 @@ bool ASTContext::isObjCObjectPointerType(QualType Ty) const { /// FIXME: When the dust settles on this integration, fold this into mergeTypes. /// bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) { - return getCanonicalType(lhs) == getCanonicalType(rhs); + const FunctionType *lbase = lhs->getAsFunctionType(); + const FunctionType *rbase = rhs->getAsFunctionType(); + const FunctionTypeProto *lproto = dyn_cast(lbase); + const FunctionTypeProto *rproto = dyn_cast(rbase); + if (lproto && rproto) + return !mergeTypes(lhs, rhs).isNull(); + return false; } /// areCompatVectorTypes - Return true if the two specified vector types are @@ -2179,6 +2185,19 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { return RHS; return getPointerType(ResultType); } + case Type::BlockPointer: + { + // Merge two block pointer types, while trying to preserve typedef info + QualType LHSPointee = LHS->getAsBlockPointerType()->getPointeeType(); + QualType RHSPointee = RHS->getAsBlockPointerType()->getPointeeType(); + QualType ResultType = mergeTypes(LHSPointee, RHSPointee); + if (ResultType.isNull()) return QualType(); + if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType)) + return LHS; + if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType)) + return RHS; + return getBlockPointerType(ResultType); + } case Type::ConstantArray: { const ConstantArrayType* LCAT = getAsConstantArrayType(LHS); diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c index 66bf725922..c52f0ed96b 100644 --- a/test/Sema/block-call.c +++ b/test/Sema/block-call.c @@ -24,7 +24,7 @@ int main() { int * (^IPCC2) () = IPCC; // expected-warning {{incompatible block pointer types initializing 'int *const (^)()', expected 'int *(^)()'}} - int (^IPCC3) (const int) = PFR; // expected-warning {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)(int const)'}} + int (^IPCC3) (const int) = PFR; int (^IPCC4) (int, char (^CArg) (double)); diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m new file mode 100644 index 0000000000..dd8380aea9 --- /dev/null +++ b/test/SemaObjC/blocks.m @@ -0,0 +1,22 @@ +// RUN: clang -fsyntax-only -verify -fblocks %s +@protocol NSObject; + +void bar(id(^)(void)); +void foo(id (^objectCreationBlock)(void)) { + return bar(objectCreationBlock); +} + +void bar2(id(*)(void)); +void foo2(id (*objectCreationBlock)(void)) { + return bar2(objectCreationBlock); +} + +void bar3(id(*)()); +void foo3(id (*objectCreationBlock)(int)) { + return bar3(objectCreationBlock); +} + +void bar4(id(^)()); +void foo4(id (^objectCreationBlock)(int)) { + return bar4(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)()'}} +}