1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs
2
3 extern char version[];
4
5 class C {
6 public:
7 C(int);
8 void g(int a, ...);
9 static void h(int a, ...);
10 };
11
12 void g(int a, ...);
13
t1()14 void t1()
15 {
16 C c(10);
17
18 g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
19 g(10, version);
20
21 void (*ptr)(int, ...) = g;
22 ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
23 ptr(10, version);
24 }
25
t2()26 void t2()
27 {
28 C c(10);
29
30 c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
31 c.g(10, version);
32
33 void (C::*ptr)(int, ...) = &C::g;
34 (c.*ptr)(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
35 (c.*ptr)(10, version);
36
37 C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
38 C::h(10, version);
39
40 void (*static_ptr)(int, ...) = &C::h;
41 static_ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
42 static_ptr(10, version);
43 }
44
45 int (^block)(int, ...);
46
t3()47 void t3()
48 {
49 C c(10);
50
51 block(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
52 block(10, version);
53 }
54
55 class D {
56 public:
57 void operator() (int a, ...);
58 };
59
t4()60 void t4()
61 {
62 C c(10);
63
64 D d;
65
66 d(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
67 d(10, version);
68 }
69
70 class E {
71 E(int, ...); // expected-note 2{{implicitly declared private here}}
72 };
73
t5()74 void t5()
75 {
76 C c(10);
77
78 E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \
79 // expected-error{{calling a private constructor of class 'E'}}
80 (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \
81 // expected-error{{calling a private constructor of class 'E'}}
82
83 }
84
85 // PR5761: unevaluated operands and the non-POD warning
86 class Foo {
87 public:
Foo()88 Foo() {}
89 };
90
91 int Helper(...);
92 const int size = sizeof(Helper(Foo()));
93
94 namespace std {
95 class type_info { };
96 }
97
98 struct Base { virtual ~Base(); };
99 Base &get_base(...);
100 int eat_base(...);
101
test_typeid(Base & base)102 void test_typeid(Base &base) {
103 (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
104 (void)typeid(eat_base(base)); // okay
105 }
106
107
108 // rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is
109 // magic.
110
t6(Foo somearg,...)111 void t6(Foo somearg, ... ) {
112 __builtin_va_list list;
113 __builtin_va_start(list, somearg);
114 }
115
t7(int n,...)116 void t7(int n, ...) {
117 __builtin_va_list list;
118 __builtin_va_start(list, n);
119 (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}
120 __builtin_va_end(list);
121 }
122
123 struct Abstract {
124 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}}
125 };
126
t8(int n,...)127 void t8(int n, ...) {
128 __builtin_va_list list;
129 __builtin_va_start(list, n);
130 (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}
131 __builtin_va_end(list);
132 }
133
t9(int n)134 int t9(int n) {
135 // Make sure the error works in potentially-evaluated sizeof
136 return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); // expected-warning{{cannot pass object of non-POD type}}
137 }
138
139 // PR14057
140 namespace t10 {
141 struct F {
142 F();
143 };
144
145 struct S {
146 void operator()(F, ...);
147 };
148
foo()149 void foo() {
150 S s;
151 F f;
152 s.operator()(f);
153 s(f);
154 }
155 }
156
157 namespace t11 {
158 typedef void(*function_ptr)(int, ...);
159 typedef void(C::*member_ptr)(int, ...);
160 typedef void(^block_ptr)(int, ...);
161
162 function_ptr get_f_ptr();
163 member_ptr get_m_ptr();
164 block_ptr get_b_ptr();
165
166 function_ptr arr_f_ptr[5];
167 member_ptr arr_m_ptr[5];
168 block_ptr arr_b_ptr[5];
169
test()170 void test() {
171 C c(10);
172
173 (get_f_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
174 (get_f_ptr())(10, version);
175
176 (c.*get_m_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
177 (c.*get_m_ptr())(10, version);
178
179 (get_b_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
180 (get_b_ptr())(10, version);
181
182 (arr_f_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
183 (arr_f_ptr[3])(10, version);
184
185 (c.*arr_m_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
186 (c.*arr_m_ptr[3])(10, version);
187
188 (arr_b_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
189 (arr_b_ptr[3])(10, version);
190 }
191 }
192