1// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -fblocks %s 2 3#define bool _Bool 4@protocol NSObject; 5 6void bar(id(^)(void)); 7void foo(id <NSObject>(^objectCreationBlock)(void)) { 8 return bar(objectCreationBlock); 9} 10 11void bar2(id(*)(void)); 12void foo2(id <NSObject>(*objectCreationBlock)(void)) { 13 return bar2(objectCreationBlock); 14} 15 16void bar3(id(*)()); 17void foo3(id (*objectCreationBlock)(int)) { 18 return bar3(objectCreationBlock); 19} 20 21void bar4(id(^)()); 22void foo4(id (^objectCreationBlock)(int)) { 23 return bar4(objectCreationBlock); 24} 25 26void bar5(id(^)(void)); // expected-note 3{{passing argument to parameter here}} 27void 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 35void bar6(id(^)(int)); 36void foo6(id (^objectCreationBlock)()) { 37 return bar6(objectCreationBlock); 38} 39 40void foo7(id (^x)(int)) { 41 if (x) { } 42} 43 44@interface itf 45@end 46 47void 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 55int 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 68extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); 69 70void 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. 80enum CStyleEnum { 81 CSE_Value = 1, 82 CSE_Value2 = 2 83}; 84enum CStyleEnum getCSE(); 85typedef enum CStyleEnum (^cse_block_t)(); 86 87void 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 142enum FixedTypeEnum : unsigned { 143 FTE_Value = 1U 144}; 145enum FixedTypeEnum getFTE(); 146typedef enum FixedTypeEnum (^fte_block_t)(); 147 148void 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 186enum { 187 AnonymousValue = 1 188}; 189 190enum : short { 191 FixedAnonymousValue = 1 192}; 193 194typedef enum { 195 TDE_Value 196} TypeDefEnum; 197TypeDefEnum getTDE(); 198 199typedef enum : short { 200 TDFTE_Value 201} TypeDefFixedTypeEnum; 202TypeDefFixedTypeEnum getTDFTE(); 203 204typedef int (^int_block_t)(); 205typedef short (^short_block_t)(); 206void 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 220static inline void inlinefunc() { 221 ^{}(); 222} 223void inlinefunccaller() { inlinefunc(); } 224