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