From aab0f7a749e939d1d485a436f57ae56d14ba3016 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 1 Apr 2009 01:17:39 +0000 Subject: [PATCH] Fix block comparisons. Radar 6732116. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68171 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 6 ++--- lib/CodeGen/CGBlocks.cpp | 15 ++++++----- test/Sema/block-call.c | 2 +- test/Sema/block-misc.c | 57 ++++++++++++++++++++++------------------ test/SemaObjC/blocks.m | 14 ++++++++-- 5 files changed, 55 insertions(+), 39 deletions(-) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index cede0e5563..bdc7e4484c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2701,9 +2701,9 @@ bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) { const FunctionType *rbase = rhs->getAsFunctionType(); const FunctionProtoType *lproto = dyn_cast(lbase); const FunctionProtoType *rproto = dyn_cast(rbase); - if (lproto && rproto) - return !mergeTypes(lhs, rhs).isNull(); - return false; + if (lproto && rproto == 0) + return false; + return !mergeTypes(lhs, rhs).isNull(); } /// areCompatVectorTypes - Return true if the two specified vector types are diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 16e926ba64..c05d3235dd 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -412,18 +412,19 @@ const llvm::Type *BlockModule::getGenericExtendedBlockLiteralType() { /// function type for the block, including the first block literal argument. static QualType getBlockFunctionType(ASTContext &Ctx, const BlockPointerType *BPT) { - const FunctionProtoType *FTy = cast(BPT->getPointeeType()); + const FunctionProtoType *FTy = dyn_cast(BPT->getPointeeType()); + const clang::QualType ResType = BPT->getPointeeType()->getAsFunctionType()->getResultType(); llvm::SmallVector Types; Types.push_back(Ctx.getPointerType(Ctx.VoidTy)); - for (FunctionProtoType::arg_type_iterator i = FTy->arg_type_begin(), - e = FTy->arg_type_end(); i != e; ++i) - Types.push_back(*i); + if (FTy) + for (FunctionProtoType::arg_type_iterator i = FTy->arg_type_begin(), + e = FTy->arg_type_end(); i != e; ++i) + Types.push_back(*i); - return Ctx.getFunctionType(FTy->getResultType(), - &Types[0], Types.size(), - FTy->isVariadic(), 0); + return Ctx.getFunctionType(ResType, &Types[0], Types.size(), + FTy && FTy->isVariadic(), 0); } RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) { diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c index 3326131816..34de8b611d 100644 --- a/test/Sema/block-call.c +++ b/test/Sema/block-call.c @@ -10,7 +10,7 @@ int main() { int (^PFR) (int) = IFP; // expected-warning {{incompatible block pointer types initializing 'int (^)()', expected 'int (^)(int)'}} PFR = II; // OK - int (^IFP) () = PFR; // expected-warning {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)()'}} + int (^IFP) () = PFR; const int (^CIC) () = IFP; // expected-warning {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}} diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c index dde07f0739..ea3477d263 100644 --- a/test/Sema/block-misc.c +++ b/test/Sema/block-misc.c @@ -4,48 +4,48 @@ void donotwarn(); int (^IFP) (); int (^II) (int); int test1() { - int (^PFR) (int) = 0; // OK - PFR = II; // OK + int (^PFR) (int) = 0; // OK + PFR = II; // OK - if (PFR == II) // OK - donotwarn(); + if (PFR == II) // OK + donotwarn(); - if (PFR == IFP) // expected-error {{comparison of distinct block types}} - donotwarn(); + if (PFR == IFP) // expected-error {{comparison of distinct block types}} + donotwarn(); - if (PFR == (int (^) (int))IFP) // OK - donotwarn(); + if (PFR == (int (^) (int))IFP) // OK + donotwarn(); - if (PFR == 0) // OK - donotwarn(); + if (PFR == 0) // OK + donotwarn(); - if (PFR) // OK - donotwarn(); + if (PFR) // OK + donotwarn(); - if (!PFR) // OK - donotwarn(); + if (!PFR) // OK + donotwarn(); - return PFR != IFP; // expected-error {{comparison of distinct block types}} + return PFR != IFP; // expected-error {{comparison of distinct block types}} } int test2(double (^S)()) { - double (^I)(int) = (void*) S; - (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}} + double (^I)(int) = (void*) S; + (void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}} - void *pv = I; + void *pv = I; - pv = S; + pv = S; - I(1); - - return (void*)I == (void *)S; + I(1); + + return (void*)I == (void *)S; } int^ x; // expected-error {{block pointer to non-function type is invalid}} int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}} int test3() { - char *^ y; // expected-error {{block pointer to non-function type is invalid}} + char *^ y; // expected-error {{block pointer to non-function type is invalid}} } @@ -72,8 +72,13 @@ void test5() { // rdar://6405429 - __func__ in a block refers to the containing function name. const char*test6() { - return ^{ - return __func__; - } (); + return ^{ + return __func__; + } (); } +// radr://6732116 - block comparisons +void (^g)(); +int foo(void (^p)()) { + return g == p; +} diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m index 6d525a990c..fe14287c7e 100644 --- a/test/SemaObjC/blocks.m +++ b/test/SemaObjC/blocks.m @@ -18,9 +18,19 @@ void foo3(id (*objectCreationBlock)(int)) { void bar4(id(^)()); void foo4(id (^objectCreationBlock)(int)) { - return bar4(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)()'}} + return bar4(objectCreationBlock); } -void foo5(id (^x)(int)) { +void bar5(id(^)(void)); +void foo5(id (^objectCreationBlock)(int)) { + return bar5(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)(void)'}} +} + +void bar6(id(^)(int)); +void foo6(id (^objectCreationBlock)()) { + return bar6(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)()', expected 'id (^)(int)'}} +} + +void foo67(id (^x)(int)) { if (x) { } } -- 2.40.0