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