222 lines · plain
1// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -fblocks -Wno-strict-prototypes %s2 3#define bool _Bool4@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 bool30 bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}}31#define bool int32 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 itf45@end46 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 the77// enumeration they are part of. We pretend the constants have enum type if78// all the returns seem to be playing along.79enum CStyleEnum {80 CSE_Value = 1,81 CSE_Value2 = 282};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 else113 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 else120 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 else127 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 = 1U142};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 a153 // 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 else172 return FTE_Value;173 };174 175 a = ^{176 if (arg)177 return FTE_Value;178 else179 return 1U;180 };181}182 183 184enum {185 AnonymousValue = 1186};187 188enum : short {189 FixedAnonymousValue = 1190};191 192typedef enum {193 TDE_Value194} TypeDefEnum;195TypeDefEnum getTDE();196 197typedef enum : short {198 TDFTE_Value199} 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 considered211 // 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