1// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -fblocks -Wno-strict-prototypes %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@class NSString; 66 67extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); 68 69void foo10() { 70 void(^myBlock)(void) = ^{ 71 }; 72 NSLog(@"%@", myBlock); 73} 74 75 76// In C, enum constants have the type of the underlying integer type, not the 77// enumeration they are part of. We pretend the constants have enum type if 78// all the returns seem to be playing along. 79enum CStyleEnum { 80 CSE_Value = 1, 81 CSE_Value2 = 2 82}; 83enum CStyleEnum getCSE(); 84typedef enum CStyleEnum (^cse_block_t)(); 85 86void testCStyleEnumInference(bool arg) { 87 cse_block_t a; 88 enum CStyleEnum value; 89 90 // No warnings here. 91 a = ^{ return getCSE(); }; 92 a = ^{ return value; }; 93 94 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 95 return 1; 96 }; 97 98 // No warning here. 99 a = ^{ 100 return CSE_Value; 101 }; 102 103 // No warnings here. 104 a = ^{ if (arg) return CSE_Value; else return getCSE(); }; 105 a = ^{ if (arg) return getCSE(); else return CSE_Value; }; 106 a = ^{ if (arg) return value; else return CSE_Value; }; 107 108 // These two blocks actually return 'int' 109 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 110 if (arg) 111 return 1; 112 else 113 return CSE_Value; 114 }; 115 116 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 117 if (arg) 118 return CSE_Value; 119 else 120 return 1; 121 }; 122 123 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}} 124 if (arg) 125 return 1; 126 else 127 return value; // expected-error {{return type 'enum CStyleEnum' must match previous return type 'int'}} 128 }; 129 130 extern void check_enum(void); 131 a = ^{ 132 return (arg ? (CSE_Value) : (check_enum(), (!arg ? CSE_Value2 : getCSE()))); 133 }; 134 a = ^{ 135 return (arg ? (CSE_Value) : ({check_enum(); CSE_Value2; })); 136 }; 137} 138 139 140enum FixedTypeEnum : unsigned { 141 FTE_Value = 1U 142}; 143enum FixedTypeEnum getFTE(); 144typedef enum FixedTypeEnum (^fte_block_t)(); 145 146void testFixedTypeEnumInference(bool arg) { 147 fte_block_t a; 148 149 // No warnings here. 150 a = ^{ return getFTE(); }; 151 152 // Since we fixed the underlying type of the enum, this is considered a 153 // compatible block type. 154 a = ^{ 155 return 1U; 156 }; 157 a = ^{ 158 return FTE_Value; 159 }; 160 161 // No warnings here. 162 a = ^{ if (arg) return FTE_Value; else return FTE_Value; }; 163 a = ^{ if (arg) return getFTE(); else return getFTE(); }; 164 a = ^{ if (arg) return FTE_Value; else return getFTE(); }; 165 a = ^{ if (arg) return getFTE(); else return FTE_Value; }; 166 167 // These two blocks actually return 'unsigned'. 168 a = ^{ 169 if (arg) 170 return 1U; 171 else 172 return FTE_Value; 173 }; 174 175 a = ^{ 176 if (arg) 177 return FTE_Value; 178 else 179 return 1U; 180 }; 181} 182 183 184enum { 185 AnonymousValue = 1 186}; 187 188enum : short { 189 FixedAnonymousValue = 1 190}; 191 192typedef enum { 193 TDE_Value 194} TypeDefEnum; 195TypeDefEnum getTDE(); 196 197typedef enum : short { 198 TDFTE_Value 199} TypeDefFixedTypeEnum; 200TypeDefFixedTypeEnum getTDFTE(); 201 202typedef int (^int_block_t)(); 203typedef short (^short_block_t)(); 204void testAnonymousEnumTypes(int arg) { 205 int_block_t IB; 206 IB = ^{ return AnonymousValue; }; 207 IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; 208 IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; 209 210 // Since we fixed the underlying type of the enum, these are considered 211 // compatible block types anyway. 212 short_block_t SB; 213 SB = ^{ return FixedAnonymousValue; }; 214 SB = ^{ if (arg) return TDFTE_Value; else return getTDFTE(); }; 215 SB = ^{ if (arg) return getTDFTE(); else return TDFTE_Value; }; 216} 217 218static inline void inlinefunc() { 219 ^{}(); 220} 221void inlinefunccaller() { inlinefunc(); } 222