blob: 9926b0835f533d658a7958c4420babc9be6ca760 [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
Douglas Gregor30c42402011-09-27 22:38:19 +00002
3#define bool _Bool
Steve Naroffc0febd52008-12-10 17:49:55 +00004@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)) {
Mike Stumpaab0f7a2009-04-01 01:17:39 +000023 return bar4(objectCreationBlock);
Steve Naroffc0febd52008-12-10 17:49:55 +000024}
Douglas Gregor2a7e58d2008-12-23 00:53:59 +000025
Douglas Gregor8987b232011-09-27 23:30:47 +000026void bar5(id(^)(void)); // expected-note 3{{passing argument to parameter here}}
Douglas Gregor30c42402011-09-27 22:38:19 +000027void foo5(id (^objectCreationBlock)(bool)) {
Douglas Gregor8987b232011-09-27 23:30:47 +000028 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)'}}
Mike Stumpaab0f7a2009-04-01 01:17:39 +000033}
34
35void bar6(id(^)(int));
36void foo6(id (^objectCreationBlock)()) {
Eli Friedman687abff2009-06-08 04:24:21 +000037 return bar6(objectCreationBlock);
Mike Stumpaab0f7a2009-04-01 01:17:39 +000038}
39
Chris Lattnerbb749822009-04-11 19:17:25 +000040void foo7(id (^x)(int)) {
Douglas Gregor2a7e58d2008-12-23 00:53:59 +000041 if (x) { }
42}
Chris Lattnerbb749822009-04-11 19:17:25 +000043
44@interface itf
45@end
46
47void foo8() {
Richard Trieu2fe9b7f2011-12-15 00:38:15 +000048 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'}}
Chris Lattnerbb749822009-04-11 19:17:25 +000052}
Fariborz Jahaniana5e42a82009-08-14 21:53:27 +000053
54
55int foo9() {
56 typedef void (^DVTOperationGroupScheduler)();
57 id _suboperationSchedulers;
58
59 for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) {
60 ;
61 }
62
63}
Fariborz Jahanian2263f822010-03-09 18:34:52 +000064
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
Jordan Rose81a56412012-06-21 05:54:55 +000076
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 when
Jordan Rose7dd900e2012-07-02 21:19:23 +000079// they are mixed with other expressions of enum type.
Jordan Rose81a56412012-06-21 05:54:55 +000080enum CStyleEnum {
81 CSE_Value = 1
82};
83enum CStyleEnum getCSE();
84typedef enum CStyleEnum (^cse_block_t)();
85
86void testCStyleEnumInference(bool arg) {
87 cse_block_t a;
88
89 // No warnings here.
Jordan Rose81a56412012-06-21 05:54:55 +000090 a = ^{ return getCSE(); };
91
92 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
93 return 1;
94 };
Jordan Rose7dd900e2012-07-02 21:19:23 +000095 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
96 return CSE_Value;
97 };
Jordan Rose81a56412012-06-21 05:54:55 +000098
99 // No warnings here.
Jordan Rose81a56412012-06-21 05:54:55 +0000100 a = ^{ if (arg) return CSE_Value; else return getCSE(); };
101 a = ^{ if (arg) return getCSE(); else return CSE_Value; };
102
Jordan Rose7dd900e2012-07-02 21:19:23 +0000103 // These two blocks actually return 'int'
Jordan Rose81a56412012-06-21 05:54:55 +0000104 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
105 if (arg)
106 return 1;
107 else
Jordan Rose7dd900e2012-07-02 21:19:23 +0000108 return CSE_Value;
Jordan Rose81a56412012-06-21 05:54:55 +0000109 };
110
Jordan Rose7dd900e2012-07-02 21:19:23 +0000111 a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
Jordan Rose81a56412012-06-21 05:54:55 +0000112 if (arg)
113 return CSE_Value;
114 else
Jordan Rose7dd900e2012-07-02 21:19:23 +0000115 return 1;
Jordan Rose81a56412012-06-21 05:54:55 +0000116 };
117}
118
119
120enum FixedTypeEnum : unsigned {
121 FTE_Value = 1U
122};
123enum FixedTypeEnum getFTE();
124typedef enum FixedTypeEnum (^fte_block_t)();
125
126void testFixedTypeEnumInference(bool arg) {
127 fte_block_t a;
128
129 // No warnings here.
Jordan Rose81a56412012-06-21 05:54:55 +0000130 a = ^{ return getFTE(); };
131
132 // Since we fixed the underlying type of the enum, this is considered a
133 // compatible block type.
134 a = ^{
135 return 1U;
136 };
Jordan Rose7dd900e2012-07-02 21:19:23 +0000137 a = ^{
138 return FTE_Value;
139 };
140
Jordan Rose81a56412012-06-21 05:54:55 +0000141 // No warnings here.
142 a = ^{ if (arg) return FTE_Value; else return FTE_Value; };
143 a = ^{ if (arg) return getFTE(); else return getFTE(); };
144 a = ^{ if (arg) return FTE_Value; else return getFTE(); };
145 a = ^{ if (arg) return getFTE(); else return FTE_Value; };
146
Jordan Rose7dd900e2012-07-02 21:19:23 +0000147 // These two blocks actually return 'unsigned'.
Jordan Rose81a56412012-06-21 05:54:55 +0000148 a = ^{
149 if (arg)
150 return 1U;
151 else
Jordan Rose7dd900e2012-07-02 21:19:23 +0000152 return FTE_Value;
Jordan Rose81a56412012-06-21 05:54:55 +0000153 };
154
155 a = ^{
156 if (arg)
157 return FTE_Value;
158 else
Jordan Rose7dd900e2012-07-02 21:19:23 +0000159 return 1U;
Jordan Rose81a56412012-06-21 05:54:55 +0000160 };
161}
162
163
164enum {
165 AnonymousValue = 1
166};
167
168enum : short {
169 FixedAnonymousValue = 1
170};
171
172typedef enum {
173 TDE_Value
174} TypeDefEnum;
Jordan Rose7dd900e2012-07-02 21:19:23 +0000175TypeDefEnum getTDE();
Jordan Rose81a56412012-06-21 05:54:55 +0000176
177typedef enum : short {
178 TDFTE_Value
179} TypeDefFixedTypeEnum;
Jordan Rose7dd900e2012-07-02 21:19:23 +0000180TypeDefFixedTypeEnum getTDFTE();
Jordan Rose81a56412012-06-21 05:54:55 +0000181
182typedef int (^int_block_t)();
183typedef short (^short_block_t)();
Jordan Rose7dd900e2012-07-02 21:19:23 +0000184void testAnonymousEnumTypes(int arg) {
Jordan Rose81a56412012-06-21 05:54:55 +0000185 int_block_t IB;
186 IB = ^{ return AnonymousValue; };
Jordan Rose7dd900e2012-07-02 21:19:23 +0000187 IB = ^{ if (arg) return TDE_Value; else return getTDE(); }; // expected-error {{incompatible block pointer}}
188 IB = ^{ if (arg) return getTDE(); else return TDE_Value; }; // expected-error {{incompatible block pointer}}
Jordan Rose81a56412012-06-21 05:54:55 +0000189
Jordan Rose7dd900e2012-07-02 21:19:23 +0000190 // Since we fixed the underlying type of the enum, these are considered
191 // compatible block types anyway.
Jordan Rose81a56412012-06-21 05:54:55 +0000192 short_block_t SB;
193 SB = ^{ return FixedAnonymousValue; };
Jordan Rose7dd900e2012-07-02 21:19:23 +0000194 SB = ^{ if (arg) return TDFTE_Value; else return getTDFTE(); };
195 SB = ^{ if (arg) return getTDFTE(); else return TDFTE_Value; };
Jordan Rose81a56412012-06-21 05:54:55 +0000196}