aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-02-12 19:07:46 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-02-12 19:07:46 +0000
commite3c8c64e7735c3589e1a34e6000c93183a55920c (patch)
tree9aba919860f16004c3c529a163b08c934dce0a14 /test
parent020c374273ab6099acbed747a7f27aebf8f0af1d (diff)
Implement objective-c++'s block pointer type matching involving
types which are contravariance in argument types and covariance in return types. // rdar://8979379. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125445 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CodeGenObjCXX/blocks.mm30
-rw-r--r--test/SemaCXX/block-call.cpp52
-rw-r--r--test/SemaObjCXX/blocks.mm16
3 files changed, 97 insertions, 1 deletions
diff --git a/test/CodeGenObjCXX/blocks.mm b/test/CodeGenObjCXX/blocks.mm
new file mode 100644
index 0000000000..ffb916bf03
--- /dev/null
+++ b/test/CodeGenObjCXX/blocks.mm
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -triple x86_64-apple-darwin %s
+// rdar://8979379
+
+@interface A
+@end
+
+@interface B : A
+@end
+
+void f(int (^bl)(B* b));
+
+// Test1
+void g() {
+ f(^(A* a) { return 0; });
+}
+
+// Test2
+void g1() {
+ int (^bl)(B* b) = ^(A* a) { return 0; };
+}
+
+// Test3
+@protocol NSObject;
+
+void bar(id(^)(void));
+
+void foo(id <NSObject>(^objectCreationBlock)(void)) {
+ return bar(objectCreationBlock);
+}
+
diff --git a/test/SemaCXX/block-call.cpp b/test/SemaCXX/block-call.cpp
new file mode 100644
index 0000000000..d519911589
--- /dev/null
+++ b/test/SemaCXX/block-call.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s -fblocks
+
+int (*FP)();
+int (^IFP) ();
+int (^II) (int);
+int main() {
+ int (*FPL) (int) = FP; // expected-error {{cannot initialize a variable of type 'int (*)(int)' with an lvalue of type 'int (*)()'}}
+
+ // For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error.
+ int (^PFR) (int) = IFP; // expected-error {{cannot initialize a variable of type 'int (^)(int)' with an lvalue of type 'int (^)()'}}
+ PFR = II; // OK
+
+ int (^IFP) () = PFR; // OK
+
+
+ const int (^CIC) () = IFP; // OK - initializing 'const int (^)()' with an expression of type 'int (^)()'}}
+
+ const int (^CICC) () = CIC;
+
+
+ int * const (^IPCC) () = 0;
+
+ int * const (^IPCC1) () = IPCC;
+
+ int * (^IPCC2) () = IPCC; // expected-error {{cannot initialize a variable of type 'int *(^)()' with an lvalue of type 'int *const (^)()'}}
+
+ int (^IPCC3) (const int) = PFR;
+
+ int (^IPCC4) (int, char (^CArg) (double));
+
+ int (^IPCC5) (int, char (^CArg) (double)) = IPCC4;
+
+ int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-error {{cannot initialize a variable of type 'int (^)(int, char (^)(float))' with an lvalue of type}}
+
+ IPCC2 = 0;
+ IPCC2 = 1;
+ int (^x)() = 0;
+ int (^y)() = 3; // expected-error {{cannot initialize a variable of type 'int (^)()' with an rvalue of type 'int'}}
+ int a = 1;
+ int (^z)() = a+4; // expected-error {{cannot initialize a variable of type 'int (^)()' with an rvalue of type 'int'}}
+}
+
+int blah() {
+ int (^IFP) (float);
+ char (^PCP)(double, double, char);
+
+ IFP(1.0);
+ IFP (1.0, 2.0); // expected-error {{too many arguments to block call}}
+
+ char ch = PCP(1.0, 2.0, 'a');
+ return PCP(1.0, 2.0); // expected-error {{too few arguments to block}}
+}
diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
index 0108ed4f90..6c2343df0e 100644
--- a/test/SemaObjCXX/blocks.mm
+++ b/test/SemaObjCXX/blocks.mm
@@ -3,7 +3,7 @@
void bar(id(^)(void));
void foo(id <NSObject>(^objectCreationBlock)(void)) {
- return bar(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id<NSObject> (^)()' to parameter of type 'id (^)()'}}
+ return bar(objectCreationBlock); // OK
}
void bar2(id(*)(void));
@@ -104,3 +104,17 @@ namespace N3 {
X<N> xN = ^() { return X<N>(); }();
}
}
+
+// rdar://8979379
+
+@interface A
+@end
+
+@interface B : A
+@end
+
+void f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no known conversion from 'int (^)(B *)' to 'int (^)(A *)' for 1st argument}}
+
+void g() {
+ f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}}
+}