1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -Wincompatible-pointer-types |
2 | |
3 | int var __attribute__((overloadable)); // expected-error{{'overloadable' attribute only applies to functions}} |
4 | void params(void) __attribute__((overloadable(12))); // expected-error {{'overloadable' attribute takes no arguments}} |
5 | |
6 | int *f(int) __attribute__((overloadable)); // expected-note{{previous overload of function is here}} |
7 | float *f(float); |
8 | int *f(int); // expected-error{{redeclaration of 'f' must have the 'overloadable' attribute}} \ |
9 | // expected-note{{previous declaration is here}} |
10 | double *f(double) __attribute__((overloadable)); // okay, new |
11 | |
12 | // Ensure we don't complain about overloadable on implicitly declared functions. |
13 | int isdigit(int) __attribute__((overloadable)); |
14 | |
15 | void test_f(int iv, float fv, double dv) { |
16 | int *ip = f(iv); |
17 | float *fp = f(fv); |
18 | double *dp = f(dv); |
19 | } |
20 | |
21 | int *accept_funcptr(int (*)()) __attribute__((overloadable)); // \ |
22 | // expected-note{{candidate function}} |
23 | float *accept_funcptr(int (*)(int, double)) __attribute__((overloadable)); // \ |
24 | // expected-note{{candidate function}} |
25 | |
26 | void test_funcptr(int (*f1)(int, double), |
27 | int (*f2)(int, float)) { |
28 | float *fp = accept_funcptr(f1); |
29 | accept_funcptr(f2); // expected-error{{call to 'accept_funcptr' is ambiguous}} |
30 | } |
31 | |
32 | struct X { int x; float y; }; |
33 | struct Y { int x; float y; }; |
34 | int* accept_struct(struct X x) __attribute__((__overloadable__)); |
35 | float* accept_struct(struct Y y) __attribute__((overloadable)); |
36 | |
37 | void test_struct(struct X x, struct Y y) { |
38 | int *ip = accept_struct(x); |
39 | float *fp = accept_struct(y); |
40 | } |
41 | |
42 | double *f(int) __attribute__((overloadable)); // expected-error{{conflicting types for 'f'}} |
43 | |
44 | double promote(float) __attribute__((__overloadable__)); |
45 | double promote(double) __attribute__((__overloadable__)); |
46 | long double promote(long double) __attribute__((__overloadable__)); |
47 | |
48 | void promote(...) __attribute__((__overloadable__, __unavailable__)); // expected-note {{marked unavailable here}} |
49 | |
50 | void test_promote(short* sp) { |
51 | promote(1.0); |
52 | promote(sp); // expected-error{{'promote' is unavailable}} |
53 | } |
54 | |
55 | // PR6600 |
56 | typedef double Double; |
57 | typedef Double DoubleVec __attribute__((vector_size(16))); |
58 | typedef int Int; |
59 | typedef Int IntVec __attribute__((vector_size(16))); |
60 | double magnitude(DoubleVec) __attribute__((__overloadable__)); |
61 | double magnitude(IntVec) __attribute__((__overloadable__)); |
62 | double test_p6600(DoubleVec d) { |
63 | return magnitude(d) * magnitude(d); |
64 | } |
65 | |
66 | // PR7738 |
67 | extern int __attribute__((overloadable)) f0(); // expected-error{{'overloadable' function 'f0' must have a prototype}} |
68 | typedef int f1_type(); |
69 | f1_type __attribute__((overloadable)) f1; // expected-error{{'overloadable' function 'f1' must have a prototype}} |
70 | |
71 | void test() { |
72 | f0(); |
73 | f1(); |
74 | } |
75 | |
76 | void before_local_1(int) __attribute__((overloadable)); |
77 | void before_local_2(int); // expected-note {{here}} |
78 | void before_local_3(int) __attribute__((overloadable)); |
79 | void local() { |
80 | void before_local_1(char); |
81 | void before_local_2(char); // expected-error {{conflicting types}} |
82 | void before_local_3(char) __attribute__((overloadable)); |
83 | void after_local_1(char); |
84 | void after_local_2(char) __attribute__((overloadable)); |
85 | void after_local_3(char) __attribute__((overloadable)); |
86 | } |
87 | void after_local_1(int) __attribute__((overloadable)); |
88 | void after_local_2(int); |
89 | void after_local_3(int) __attribute__((overloadable)); |
90 | |
91 | // Make sure we allow C-specific conversions in C. |
92 | void conversions() { |
93 | void foo(char *c) __attribute__((overloadable)); |
94 | void foo(char *c) __attribute__((overloadable, enable_if(c, "nope.jpg"))); |
95 | |
96 | void *ptr; |
97 | foo(ptr); |
98 | |
99 | void multi_type(unsigned char *c) __attribute__((overloadable)); |
100 | void multi_type(signed char *c) __attribute__((overloadable)); |
101 | unsigned char *c; |
102 | multi_type(c); |
103 | } |
104 | |
105 | // Ensure that we allow C-specific type conversions in C |
106 | void fn_type_conversions() { |
107 | void foo(void *c) __attribute__((overloadable)); |
108 | void foo(char *c) __attribute__((overloadable)); |
109 | void (*ptr1)(void *) = &foo; |
110 | void (*ptr2)(char *) = &foo; |
111 | void (*ambiguous)(int *) = &foo; // expected-error{{initializing 'void (*)(int *)' with an expression of incompatible type '<overloaded function type>'}} expected-note@-4{{candidate function}} expected-note@-3{{candidate function}} |
112 | void *vp_ambiguous = &foo; // expected-error{{initializing 'void *' with an expression of incompatible type '<overloaded function type>'}} expected-note@-5{{candidate function}} expected-note@-4{{candidate function}} |
113 | |
114 | void (*specific1)(int *) = (void (*)(void *))&foo; // expected-warning{{incompatible function pointer types initializing 'void (*)(int *)' with an expression of type 'void (*)(void *)'}} |
115 | void *specific2 = (void (*)(void *))&foo; |
116 | |
117 | void disabled(void *c) __attribute__((overloadable, enable_if(0, ""))); |
118 | void disabled(int *c) __attribute__((overloadable, enable_if(c, ""))); |
119 | void disabled(char *c) __attribute__((overloadable, enable_if(1, "The function name lies."))); |
120 | // To be clear, these should all point to the last overload of 'disabled' |
121 | void (*dptr1)(char *c) = &disabled; |
122 | void (*dptr2)(void *c) = &disabled; // expected-warning{{incompatible pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}} expected-note@-5{{candidate function made ineligible by enable_if}} expected-note@-4{{candidate function made ineligible by enable_if}} expected-note@-3{{candidate function has type mismatch at 1st parameter (expected 'void *' but has 'char *')}} |
123 | void (*dptr3)(int *c) = &disabled; // expected-warning{{incompatible pointer types initializing 'void (*)(int *)' with an expression of type '<overloaded function type>'}} expected-note@-6{{candidate function made ineligible by enable_if}} expected-note@-5{{candidate function made ineligible by enable_if}} expected-note@-4{{candidate function has type mismatch at 1st parameter (expected 'int *' but has 'char *')}} |
124 | |
125 | void *specific_disabled = &disabled; |
126 | } |
127 | |
128 | void incompatible_pointer_type_conversions() { |
129 | char charbuf[1]; |
130 | unsigned char ucharbuf[1]; |
131 | int intbuf[1]; |
132 | |
133 | void foo(char *c) __attribute__((overloadable)); |
134 | void foo(short *c) __attribute__((overloadable)); |
135 | foo(charbuf); |
136 | foo(ucharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@-3{{candidate function}} expected-note@-2{{candidate function}} |
137 | foo(intbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@-4{{candidate function}} expected-note@-3{{candidate function}} |
138 | |
139 | void bar(unsigned char *c) __attribute__((overloadable)); |
140 | void bar(signed char *c) __attribute__((overloadable)); |
141 | bar(charbuf); // expected-error{{call to 'bar' is ambiguous}} expected-note@-2{{candidate function}} expected-note@-1{{candidate function}} |
142 | bar(ucharbuf); |
143 | bar(intbuf); // expected-error{{call to 'bar' is ambiguous}} expected-note@-4{{candidate function}} expected-note@-3{{candidate function}} |
144 | } |
145 | |
146 | void dropping_qualifiers_is_incompatible() { |
147 | const char ccharbuf[1]; |
148 | volatile char vcharbuf[1]; |
149 | |
150 | void foo(char *c) __attribute__((overloadable)); |
151 | void foo(const volatile unsigned char *c) __attribute__((overloadable)); |
152 | |
153 | foo(ccharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@-3{{candidate function}} expected-note@-2{{candidate function}} |
154 | foo(vcharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@-4{{candidate function}} expected-note@-3{{candidate function}} |
155 | } |
156 | |
157 | void overloadable_with_global() { |
158 | void wg_foo(void) __attribute__((overloadable)); // expected-note{{previous}} |
159 | void wg_foo(int) __attribute__((overloadable)); |
160 | } |
161 | |
162 | int wg_foo; // expected-error{{redefinition of 'wg_foo' as different kind of symbol}} |
163 | |
164 | #if !__has_extension(overloadable_unmarked) |
165 | #error "We should have unmarked overload support" |
166 | #endif |
167 | |
168 | void to_foo0(int); |
169 | void to_foo0(double) __attribute__((overloadable)); // expected-note{{previous overload}} |
170 | void to_foo0(int); |
171 | void to_foo0(double); // expected-error{{must have the 'overloadable' attribute}} |
172 | void to_foo0(int); |
173 | |
174 | void to_foo1(int) __attribute__((overloadable)); // expected-note 2{{previous overload}} |
175 | void to_foo1(double); |
176 | void to_foo1(int); // expected-error{{must have the 'overloadable' attribute}} |
177 | void to_foo1(double); |
178 | void to_foo1(int); // expected-error{{must have the 'overloadable' attribute}} |
179 | |
180 | void to_foo2(int); // expected-note{{previous unmarked overload}} |
181 | void to_foo2(double) __attribute__((overloadable)); // expected-note 2{{previous overload}} |
182 | void to_foo2(int) __attribute__((overloadable)); // expected-error {{must not have the 'overloadable' attribute}} |
183 | void to_foo2(double); // expected-error{{must have the 'overloadable' attribute}} |
184 | void to_foo2(int); |
185 | void to_foo2(double); // expected-error{{must have the 'overloadable' attribute}} |
186 | void to_foo2(int); |
187 | |
188 | void to_foo3(int); |
189 | void to_foo3(double) __attribute__((overloadable)); // expected-note{{previous overload}} |
190 | void to_foo3(int); |
191 | void to_foo3(double); // expected-error{{must have the 'overloadable' attribute}} |
192 | |
193 | void to_foo4(int) __attribute__((overloadable)); // expected-note{{previous overload}} |
194 | void to_foo4(int); // expected-error{{must have the 'overloadable' attribute}} |
195 | void to_foo4(double) __attribute__((overloadable)); |
196 | |
197 | void to_foo5(int); |
198 | void to_foo5(int); // expected-note 3{{previous unmarked overload}} |
199 | void to_foo5(float) __attribute__((overloadable)); |
200 | void to_foo5(double); // expected-error{{at most one overload for a given name may lack the 'overloadable' attribute}} |
201 | void to_foo5(float) __attribute__((overloadable)); |
202 | void to_foo5(short); // expected-error{{at most one overload for a given name may lack the 'overloadable' attribute}} |
203 | void to_foo5(long); // expected-error{{at most one overload for a given name may lack the 'overloadable' attribute}} |
204 | void to_foo5(double) __attribute__((overloadable)); |
205 | |
206 | void to_foo6(int) __attribute__((enable_if(1, ""), overloadable)); // expected-note{{previous overload}} |
207 | void to_foo6(int) __attribute__((enable_if(1, ""))); // expected-error{{must have the 'overloadable' attribute}} |
208 | void to_foo6(int) __attribute__((enable_if(1, ""), overloadable)); |
209 | |
210 | void to_foo7(int) __attribute__((enable_if(1, ""))); // expected-note{{previous unmarked overload}} |
211 | void to_foo7(int) __attribute__((enable_if(1, ""), overloadable)); // expected-error{{must not have the 'overloadable' attribute}} |
212 | void to_foo7(int) __attribute__((enable_if(1, ""))); |
213 | |
214 | void to_foo8(char *__attribute__((pass_object_size(0)))) |
215 | __attribute__((enable_if(1, ""))); |
216 | void to_foo8(char *__attribute__((pass_object_size(0)))) |
217 | __attribute__((overloadable)); |
218 | |
219 | void to_foo9(int); // expected-note{{previous unmarked overload}} |
220 | // FIXME: It would be nice if we did better with the "previous unmarked |
221 | // overload" diag. |
222 | void to_foo9(int) __attribute__((overloadable)); // expected-error{{must not have the 'overloadable' attribute}} expected-note{{previous declaration}} expected-note{{previous unmarked overload}} |
223 | void to_foo9(float); // expected-error{{conflicting types for 'to_foo9'}} |
224 | void to_foo9(float) __attribute__((overloadable)); |
225 | void to_foo9(double); // expected-error{{at most one overload for a given name may lack the 'overloadable' attribute}} |
226 | void to_foo9(double) __attribute__((overloadable)); |
227 | |
228 | void to_foo10(int) __attribute__((overloadable)); |
229 | void to_foo10(double); // expected-note{{previous unmarked overload}} |
230 | // no "note: previous redecl" if no previous decl has `overloadable` |
231 | // spelled out |
232 | void to_foo10(float); // expected-error{{at most one overload for a given name may lack the 'overloadable' attribute}} |
233 | void to_foo10(float); // expected-error{{must have the 'overloadable' attribute}} |
234 | void to_foo10(float); // expected-error{{must have the 'overloadable' attribute}} |
235 | |
236 | // Bug: we used to treat `__typeof__(foo)` as though it was `__typeof__(&foo)` |
237 | // if `foo` was overloaded with only one function that could have its address |
238 | // taken. |
239 | void typeof_function_is_not_a_pointer() { |
240 | void not_a_pointer(void *) __attribute__((overloadable)); |
241 | void not_a_pointer(char *__attribute__((pass_object_size(1)))) |
242 | __attribute__((overloadable)); |
243 | |
244 | __typeof__(not_a_pointer) *fn; |
245 | |
246 | void take_fn(void (*)(void *)); |
247 | // if take_fn is passed a void (**)(void *), we'll get a warning. |
248 | take_fn(fn); |
249 | } |
250 | |