]> granicus.if.org Git - clang/commitdiff
Fix block comparisons. Radar 6732116.
authorMike Stump <mrs@apple.com>
Wed, 1 Apr 2009 01:17:39 +0000 (01:17 +0000)
committerMike Stump <mrs@apple.com>
Wed, 1 Apr 2009 01:17:39 +0000 (01:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68171 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
lib/CodeGen/CGBlocks.cpp
test/Sema/block-call.c
test/Sema/block-misc.c
test/SemaObjC/blocks.m

index cede0e556391cfee3d53f4161767e0bf644b47cf..bdc7e4484c2b9d49dc5a1475a842849d05f103e5 100644 (file)
@@ -2701,9 +2701,9 @@ bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
   const FunctionType *rbase = rhs->getAsFunctionType();
   const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
   const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(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 
index 16e926ba643cd7b9fedd08a63d749ab02186b94f..c05d3235dd89257a56bdb2fcae0135eb0cece549 100644 (file)
@@ -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<FunctionProtoType>(BPT->getPointeeType());
+  const FunctionProtoType *FTy = dyn_cast<FunctionProtoType>(BPT->getPointeeType());
+  const clang::QualType ResType = BPT->getPointeeType()->getAsFunctionType()->getResultType();
 
   llvm::SmallVector<QualType, 8> 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) {
index 3326131816e7d87a044b8ecbc2b0203d58c517ee..34de8b611d8aeb4f8096c2685da75d80b029de00 100644 (file)
@@ -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 (^)()'}}
index dde07f07394942c089a50db9d05b027e9bbf0823..ea3477d2639d10cc8f94a5ec25fdb685715e259e 100644 (file)
@@ -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;
+}
index 6d525a990ca1dfe0439baa39df89d2eff3a7045c..fe14287c7edba4434469dd49e754dd97856f2668 100644 (file)
@@ -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) { }
 }