Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaObjC / blocks.m
blob99ef0130b564b05ab4950ad8b160d26fd477d6e0
1 // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -fblocks -Wno-strict-prototypes %s
3 #define bool _Bool
4 @protocol NSObject;
6 void bar(id(^)(void));
7 void foo(id <NSObject>(^objectCreationBlock)(void)) {
8     return bar(objectCreationBlock);
11 void bar2(id(*)(void));
12 void foo2(id <NSObject>(*objectCreationBlock)(void)) {
13     return bar2(objectCreationBlock);
16 void bar3(id(*)());
17 void foo3(id (*objectCreationBlock)(int)) {
18     return bar3(objectCreationBlock);
21 void bar4(id(^)());
22 void foo4(id (^objectCreationBlock)(int)) {
23     return bar4(objectCreationBlock);
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)'}}
35 void bar6(id(^)(int));
36 void foo6(id (^objectCreationBlock)()) {
37     return bar6(objectCreationBlock);
40 void foo7(id (^x)(int)) {
41   if (x) { }
44 @interface itf
45 @end
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'}}
55 int foo9() {
56   typedef void (^DVTOperationGroupScheduler)();
57   id _suboperationSchedulers;
59   for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) {
60             ;
61         }
65 @class NSString;
67 extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
69 void foo10() {
70     void(^myBlock)(void) = ^{
71     };
72     NSLog(@"%@", myBlock);
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.
79 enum CStyleEnum {
80   CSE_Value = 1,
81   CSE_Value2 = 2
83 enum CStyleEnum getCSE();
84 typedef enum CStyleEnum (^cse_block_t)();
86 void testCStyleEnumInference(bool arg) {
87   cse_block_t a;
88   enum CStyleEnum value;
90   // No warnings here.
91   a = ^{ return getCSE(); };
92   a = ^{ return value; };
94   a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
95     return 1;
96   };
98   // No warning here.
99   a = ^{
100     return CSE_Value;
101   };
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; };
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   };
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   };
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   };
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   };
140 enum FixedTypeEnum : unsigned {
141   FTE_Value = 1U
143 enum FixedTypeEnum getFTE();
144 typedef enum FixedTypeEnum (^fte_block_t)();
146 void testFixedTypeEnumInference(bool arg) {
147   fte_block_t a;
148   
149   // No warnings here.
150   a = ^{ return getFTE(); };
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   };
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   };
184 enum {
185   AnonymousValue = 1
188 enum : short {
189   FixedAnonymousValue = 1
192 typedef enum {
193   TDE_Value
194 } TypeDefEnum;
195 TypeDefEnum getTDE();
197 typedef enum : short {
198   TDFTE_Value
199 } TypeDefFixedTypeEnum;
200 TypeDefFixedTypeEnum getTDFTE();
202 typedef int (^int_block_t)();
203 typedef short (^short_block_t)();
204 void 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; };
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; };
218 static inline void inlinefunc() {
219   ^{}();
221 void inlinefunccaller() { inlinefunc(); }