1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s 2 3 #define bool _Bool 4 @protocol NSObject; 5 6 void bar(id(^)(void)); 7 void foo(id <NSObject>(^objectCreationBlock)(void)) { 8 return bar(objectCreationBlock); 9 } 10 11 void bar2(id(*)(void)); 12 void foo2(id <NSObject>(*objectCreationBlock)(void)) { 13 return bar2(objectCreationBlock); 14 } 15 16 void bar3(id(*)()); 17 void foo3(id (*objectCreationBlock)(int)) { 18 return bar3(objectCreationBlock); 19 } 20 21 void bar4(id(^)()); 22 void foo4(id (^objectCreationBlock)(int)) { 23 return bar4(objectCreationBlock); 24 } 25 26 void bar5(id(^)(void)); // expected-note 3{{passing argument to parameter here}} 27 void foo5(id (^objectCreationBlock)(bool)) { 28 bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(bool)' to parameter of type 'id (^)(void)'}} 29 #undef bool 30 bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}} 31 #define bool int 32 bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}} 33 } 34 35 void bar6(id(^)(int)); 36 void foo6(id (^objectCreationBlock)()) { 37 return bar6(objectCreationBlock); 38 } 39 40 void foo7(id (^x)(int)) { 41 if (x) { } 42 } 43 44 @interface itf 45 @end 46 47 void foo8() { 48 void *P = ^(itf x) {}; // expected-error {{interface type 'itf' cannot be passed by value; did you forget * in 'itf'}} 49 P = ^itf(int x) {}; // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}} 50 P = ^itf() {}; // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}} 51 P = ^itf{}; // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}} 52 } 53 54 55 int foo9() { 56 typedef void (^DVTOperationGroupScheduler)(); 57 id _suboperationSchedulers; 58 59 for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) { 60 ; 61 } 62 63 } 64 65 // rdar 7725203 66 @class NSString; 67 68 extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); 69 70 void foo10() { 71 void(^myBlock)(void) = ^{ 72 }; 73 NSLog(@"%@", myBlock); 74 } 75 76 77 // In C, enum constants have the type of the underlying integer type, not the 78 // enumeration they are part of. We pretend the constants have enum type if 79 // all the returns seem to be playing along. 80 enum CStyleEnum { 81 CSE_Value = 1, 82 CSE_Value2 = 2 83 }; 84 enum CStyleEnum getCSE(); 85 typedef enum CStyleEnum (^cse_block_t)(); 86 87 void testCStyleEnumInference(bool arg) { 88 cse_block_t a; 89 enum CStyleEnum value; 90 91 // No warnings here. 92 a = ^{ return getCSE(); }; 93 a = ^{ return value; }; 94 95 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 96 return 1; 97 }; 98 99 // No warning here. 100 a = ^{ 101 return CSE_Value; 102 }; 103 104 // No warnings here. 105 a = ^{ if (arg) return CSE_Value; else return getCSE(); }; 106 a = ^{ if (arg) return getCSE(); else return CSE_Value; }; 107 a = ^{ if (arg) return value; else return CSE_Value; }; 108 109 // These two blocks actually return 'int' 110 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 111 if (arg) 112 return 1; 113 else 114 return CSE_Value; 115 }; 116 117 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 118 if (arg) 119 return CSE_Value; 120 else 121 return 1; 122 }; 123 124 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 125 if (arg) 126 return 1; 127 else 128 return value; // expected-error {{return type 'enum CStyleEnum' must match previous return type 'int'}} 129 }; 130 131 // rdar://13200889 132 extern void check_enum(void); 133 a = ^{ 134 return (arg ? (CSE_Value) : (check_enum(), (!arg ? CSE_Value2 : getCSE()))); 135 }; 136 a = ^{ 137 return (arg ? (CSE_Value) : ({check_enum(); CSE_Value2; })); 138 }; 139 } 140 141 142 enum FixedTypeEnum : unsigned { 143 FTE_Value = 1U 144 }; 145 enum FixedTypeEnum getFTE(); 146 typedef enum FixedTypeEnum (^fte_block_t)(); 147 148 void testFixedTypeEnumInference(bool arg) { 149 fte_block_t a; 150 151 // No warnings here. 152 a = ^{ return getFTE(); }; 153 154 // Since we fixed the underlying type of the enum, this is considered a 155 // compatible block type. 156 a = ^{ 157 return 1U; 158 }; 159 a = ^{ 160 return FTE_Value; 161 }; 162 163 // No warnings here. 164 a = ^{ if (arg) return FTE_Value; else return FTE_Value; }; 165 a = ^{ if (arg) return getFTE(); else return getFTE(); }; 166 a = ^{ if (arg) return FTE_Value; else return getFTE(); }; 167 a = ^{ if (arg) return getFTE(); else return FTE_Value; }; 168 169 // These two blocks actually return 'unsigned'. 170 a = ^{ 171 if (arg) 172 return 1U; 173 else 174 return FTE_Value; 175 }; 176 177 a = ^{ 178 if (arg) 179 return FTE_Value; 180 else 181 return 1U; 182 }; 183 } 184 185 186 enum { 187 AnonymousValue = 1 188 }; 189 190 enum : short { 191 FixedAnonymousValue = 1 192 }; 193 194 typedef enum { 195 TDE_Value 196 } TypeDefEnum; 197 TypeDefEnum getTDE(); 198 199 typedef enum : short { 200 TDFTE_Value 201 } TypeDefFixedTypeEnum; 202 TypeDefFixedTypeEnum getTDFTE(); 203 204 typedef int (^int_block_t)(); 205 typedef short (^short_block_t)(); 206 void testAnonymousEnumTypes(int arg) { 207 int_block_t IB; 208 IB = ^{ return AnonymousValue; }; 209 IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; 210 IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; 211 212 // Since we fixed the underlying type of the enum, these are considered 213 // compatible block types anyway. 214 short_block_t SB; 215 SB = ^{ return FixedAnonymousValue; }; 216 SB = ^{ if (arg) return TDFTE_Value; else return getTDFTE(); }; 217 SB = ^{ if (arg) return getTDFTE(); else return TDFTE_Value; }; 218 } 219 220 static inline void inlinefunc() { 221 ^{}(); 222 } 223 void inlinefunccaller() { inlinefunc(); } 224