diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-02-12 19:07:46 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-02-12 19:07:46 +0000 |
commit | e3c8c64e7735c3589e1a34e6000c93183a55920c (patch) | |
tree | 9aba919860f16004c3c529a163b08c934dce0a14 /test | |
parent | 020c374273ab6099acbed747a7f27aebf8f0af1d (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.mm | 30 | ||||
-rw-r--r-- | test/SemaCXX/block-call.cpp | 52 | ||||
-rw-r--r-- | test/SemaObjCXX/blocks.mm | 16 |
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'}} +} |