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