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