1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs
2 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs
3 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs
4
5 // Check that the warning is still there under -fms-compatibility.
6 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs -fms-compatibility
7 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs -fms-compatibility
8 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs -fms-compatibility
9
10 extern char version[];
11
12 class C {
13 public:
14 C(int);
15 void g(int a, ...);
16 static void h(int a, ...);
17 };
18
19 void g(int a, ...);
20
t1()21 void t1()
22 {
23 C c(10);
24
25 g(10, c);
26 #if __cplusplus <= 199711L
27 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
28 #endif
29
30 g(10, version);
31
32 void (*ptr)(int, ...) = g;
33 ptr(10, c);
34 #if __cplusplus <= 199711L
35 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
36 #endif
37
38 ptr(10, version);
39 }
40
t2()41 void t2()
42 {
43 C c(10);
44
45 c.g(10, c);
46 #if __cplusplus <= 199711L
47 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
48 #endif
49
50 c.g(10, version);
51
52 void (C::*ptr)(int, ...) = &C::g;
53 (c.*ptr)(10, c);
54 #if __cplusplus <= 199711L
55 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
56 #endif
57
58 (c.*ptr)(10, version);
59
60 C::h(10, c);
61 #if __cplusplus <= 199711L
62 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
63 #endif
64
65 C::h(10, version);
66
67 void (*static_ptr)(int, ...) = &C::h;
68 static_ptr(10, c);
69 #if __cplusplus <= 199711L
70 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
71 #endif
72
73 static_ptr(10, version);
74 }
75
76 int (^block)(int, ...);
77
t3()78 void t3()
79 {
80 C c(10);
81
82 block(10, c);
83 #if __cplusplus <= 199711L
84 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
85 #endif
86
87 block(10, version);
88 }
89
90 class D {
91 public:
92 void operator() (int a, ...);
93 };
94
t4()95 void t4()
96 {
97 C c(10);
98
99 D d;
100
101 d(10, c);
102 #if __cplusplus <= 199711L
103 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
104 #endif
105
106 d(10, version);
107 }
108
109 class E {
110 E(int, ...); // expected-note 2{{implicitly declared private here}}
111 };
112
t5()113 void t5()
114 {
115 C c(10);
116
117 E e(10, c);
118 #if __cplusplus <= 199711L
119 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
120 #endif
121 // expected-error@-4 {{calling a private constructor of class 'E'}}
122 (void)E(10, c);
123 #if __cplusplus <= 199711L
124 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
125 #endif
126 // expected-error@-4 {{calling a private constructor of class 'E'}}
127
128 }
129
130 // PR5761: unevaluated operands and the non-POD warning
131 class Foo {
132 public:
Foo()133 Foo() {}
134 };
135
136 int Helper(...);
137 const int size = sizeof(Helper(Foo()));
138
139 namespace std {
140 class type_info { };
141 }
142
143 struct Base { virtual ~Base(); };
144 Base &get_base(...);
145 int eat_base(...);
146
test_typeid(Base & base)147 void test_typeid(Base &base) {
148 (void)typeid(get_base(base));
149 #if __cplusplus <= 199711L
150 // expected-warning@-2 {{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
151 #else
152 // expected-warning@-4 {{cannot pass object of non-trivial type 'Base' through variadic function; call will abort at runtime}}
153 #endif
154 // expected-warning@-6 {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
155 (void)typeid(eat_base(base)); // okay
156 }
157
158
159 // rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is
160 // magic.
161
t6(Foo somearg,...)162 void t6(Foo somearg, ... ) {
163 __builtin_va_list list;
164 __builtin_va_start(list, somearg);
165 }
166
167 // __builtin_stdarg_start is a compatibility alias for __builtin_va_start,
168 // it should behave the same
t6b(Foo somearg,...)169 void t6b(Foo somearg, ... ) {
170 __builtin_va_list list;
171 __builtin_stdarg_start(list, somearg); // second argument to 'va_start' is not the last named parameter [-Wvarargs]
172 }
173
t7(int n,...)174 void t7(int n, ...) {
175 __builtin_va_list list;
176 __builtin_va_start(list, n);
177 (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}
178 __builtin_va_end(list);
179 }
180
181 struct Abstract {
182 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}}
183 };
184
t8(int n,...)185 void t8(int n, ...) {
186 __builtin_va_list list;
187 __builtin_va_start(list, n);
188 (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}
189 __builtin_va_end(list);
190 }
191
t9(int n)192 int t9(int n) {
193 // Make sure the error works in potentially-evaluated sizeof
194 return (int)sizeof(*(Helper(Foo()), (int (*)[n])0));
195 #if __cplusplus <= 199711L
196 // expected-warning@-2 {{cannot pass object of non-POD type 'Foo' through variadic function; call will abort at runtime}}
197 #endif
198 }
199
200 // PR14057
201 namespace t10 {
202 struct F {
203 F();
204 };
205
206 struct S {
207 void operator()(F, ...);
208 };
209
foo()210 void foo() {
211 S s;
212 F f;
213 s.operator()(f);
214 s(f);
215 }
216 }
217
218 namespace t11 {
219 typedef void(*function_ptr)(int, ...);
220 typedef void(C::*member_ptr)(int, ...);
221 typedef void(^block_ptr)(int, ...);
222
223 function_ptr get_f_ptr();
224 member_ptr get_m_ptr();
225 block_ptr get_b_ptr();
226
227 function_ptr arr_f_ptr[5];
228 member_ptr arr_m_ptr[5];
229 block_ptr arr_b_ptr[5];
230
test()231 void test() {
232 C c(10);
233
234 (get_f_ptr())(10, c);
235 #if __cplusplus <= 199711L
236 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
237 #endif
238 (get_f_ptr())(10, version);
239
240 (c.*get_m_ptr())(10, c);
241 #if __cplusplus <= 199711L
242 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
243 #endif
244 (c.*get_m_ptr())(10, version);
245
246 (get_b_ptr())(10, c);
247 #if __cplusplus <= 199711L
248 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
249 #endif
250
251 (get_b_ptr())(10, version);
252
253 (arr_f_ptr[3])(10, c);
254 #if __cplusplus <= 199711L
255 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
256 #endif
257
258 (arr_f_ptr[3])(10, version);
259
260 (c.*arr_m_ptr[3])(10, c);
261 #if __cplusplus <= 199711L
262 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
263 #endif
264
265 (c.*arr_m_ptr[3])(10, version);
266
267 (arr_b_ptr[3])(10, c);
268 #if __cplusplus <= 199711L
269 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
270 #endif
271 (arr_b_ptr[3])(10, version);
272 }
273 }
274