Ted Kremenek | ebcb57a | 2012-03-06 20:05:56 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fblocks %s |
| 2 | |
Fariborz Jahanian | 9985038 | 2012-04-12 17:49:18 +0000 | [diff] [blame] | 3 | // rdar://11231426 |
Fariborz Jahanian | 93a4994 | 2012-04-16 21:03:30 +0000 | [diff] [blame] | 4 | typedef signed char BOOL; |
Fariborz Jahanian | 9985038 | 2012-04-12 17:49:18 +0000 | [diff] [blame] | 5 | |
| 6 | void y(BOOL (^foo)()); |
| 7 | |
| 8 | void x() { |
| 9 | y(^{ |
| 10 | return __objc_yes; |
| 11 | }); |
| 12 | } |
Ted Kremenek | ebcb57a | 2012-03-06 20:05:56 +0000 | [diff] [blame] | 13 | |
| 14 | @protocol NSCopying |
| 15 | - copy; |
| 16 | @end |
| 17 | |
| 18 | @interface NSObject |
| 19 | @end |
| 20 | |
| 21 | @interface NSNumber : NSObject <NSCopying> |
| 22 | -copy; |
| 23 | @end |
| 24 | |
| 25 | @interface NSNumber (NSNumberCreation) |
| 26 | + (NSNumber *)numberWithChar:(char)value; |
| 27 | + (NSNumber *)numberWithUnsignedChar:(unsigned char)value; |
| 28 | + (NSNumber *)numberWithShort:(short)value; |
| 29 | + (NSNumber *)numberWithUnsignedShort:(unsigned short)value; |
| 30 | + (NSNumber *)numberWithInt:(int)value; |
| 31 | + (NSNumber *)numberWithUnsignedInt:(unsigned int)value; |
| 32 | + (NSNumber *)numberWithLong:(long)value; |
| 33 | + (NSNumber *)numberWithUnsignedLong:(unsigned long)value; |
| 34 | + (NSNumber *)numberWithLongLong:(long long)value; |
| 35 | + (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; |
| 36 | + (NSNumber *)numberWithFloat:(float)value; |
| 37 | + (NSNumber *)numberWithDouble:(double)value; |
| 38 | + (NSNumber *)numberWithBool:(BOOL)value; |
| 39 | @end |
| 40 | |
| 41 | @interface NSArray : NSObject <NSCopying> |
| 42 | -copy; |
| 43 | @end |
| 44 | |
| 45 | @interface NSArray (NSArrayCreation) |
| 46 | + (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; |
| 47 | @end |
| 48 | |
| 49 | @interface NSDictionary |
| 50 | + (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt; |
| 51 | @end |
| 52 | |
| 53 | template<typename T> |
| 54 | struct ConvertibleTo { |
| 55 | operator T(); |
| 56 | }; |
| 57 | |
| 58 | template<typename T> |
| 59 | struct ExplicitlyConvertibleTo { |
| 60 | explicit operator T(); |
| 61 | }; |
| 62 | |
| 63 | template<typename T> |
| 64 | class PrivateConvertibleTo { |
| 65 | private: |
| 66 | operator T(); // expected-note{{declared private here}} |
| 67 | }; |
| 68 | |
| 69 | template<typename T> ConvertibleTo<T> makeConvertible(); |
| 70 | |
| 71 | struct X { |
| 72 | ConvertibleTo<id> x; |
| 73 | ConvertibleTo<id> get(); |
| 74 | }; |
| 75 | |
| 76 | template<typename T> T test_numeric_instantiation() { |
| 77 | return @-17.42; |
| 78 | } |
| 79 | |
| 80 | template id test_numeric_instantiation(); |
| 81 | |
| 82 | void test_convertibility(ConvertibleTo<NSArray*> toArray, |
| 83 | ConvertibleTo<id> toId, |
| 84 | ConvertibleTo<int (^)(int)> toBlock, |
| 85 | ConvertibleTo<int> toInt, |
| 86 | ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) { |
| 87 | id array = @[ |
| 88 | toArray, |
| 89 | toId, |
| 90 | toBlock, |
| 91 | toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}} |
| 92 | ]; |
| 93 | id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}} |
| 94 | |
| 95 | id array3 = @[ |
| 96 | makeConvertible<id>(), |
| 97 | makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}} |
| 98 | ]; |
| 99 | |
| 100 | X x; |
| 101 | id array4 = @[ x.x ]; |
| 102 | id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}} |
| 103 | id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}} |
| 104 | } |
| 105 | |
| 106 | template<typename T> |
| 107 | void test_array_literals(T t) { |
| 108 | id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}} |
| 109 | } |
| 110 | |
| 111 | template void test_array_literals(id); |
| 112 | template void test_array_literals(NSArray*); |
| 113 | template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}} |
| 114 | |
| 115 | template<typename T, typename U> |
| 116 | void test_dictionary_literals(T t, U u) { |
| 117 | NSObject *object; |
| 118 | id dict = @{ |
| 119 | @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}} |
| 120 | u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}} |
| 121 | }; |
| 122 | |
| 123 | id dict2 = @{ |
| 124 | object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}} |
| 125 | }; |
| 126 | } |
| 127 | |
| 128 | template void test_dictionary_literals(id, NSArray*); |
| 129 | template void test_dictionary_literals(NSArray*, id); |
| 130 | template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}} |
| 131 | template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}} |
| 132 | |
| 133 | template<typename ...Args> |
| 134 | void test_bad_variadic_array_literal(Args ...args) { |
| 135 | id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}} |
| 136 | } |
| 137 | |
| 138 | template<typename ...Args> |
| 139 | void test_variadic_array_literal(Args ...args) { |
| 140 | id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}} |
| 141 | } |
| 142 | template void test_variadic_array_literal(id); |
| 143 | template void test_variadic_array_literal(id, NSArray*); |
| 144 | template void test_variadic_array_literal(id, int, NSArray*); // expected-note{{in instantiation of function template specialization 'test_variadic_array_literal<id, int, NSArray *>' requested here}} |
| 145 | |
| 146 | template<typename ...Args> |
| 147 | void test_bad_variadic_dictionary_literal(Args ...args) { |
| 148 | id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}} |
| 149 | } |
| 150 | |
| 151 | // Test array literal pack expansions. |
| 152 | template<typename T, typename U> |
| 153 | struct pair { |
| 154 | T first; |
| 155 | U second; |
| 156 | }; |
| 157 | |
| 158 | template<typename T, typename ...Ts, typename ... Us> |
| 159 | void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) { |
| 160 | id dict = @{ |
| 161 | t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}} |
| 162 | key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}} |
| 163 | key_values.second : t ... |
| 164 | }; |
| 165 | } |
| 166 | |
| 167 | template void test_variadic_dictionary_expansion(id, |
| 168 | pair<NSNumber*, id>, |
| 169 | pair<id, ConvertibleTo<id>>); |
| 170 | template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}} |
| 171 | pair<NSNumber*, int>, |
| 172 | pair<id, ConvertibleTo<id>>); |
| 173 | template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}} |
| 174 | pair<NSNumber*, id>, |
| 175 | pair<float, ConvertibleTo<id>>); |
| 176 | |
| 177 | // Test parsing |
| 178 | struct key { |
| 179 | static id value; |
| 180 | }; |
| 181 | |
| 182 | id key; |
| 183 | id value; |
| 184 | |
| 185 | void test_dictionary_colon() { |
| 186 | id dict = @{ key : value }; |
| 187 | } |