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 10extern char version[]; 11 12class C { 13public: 14 C(int); 15 void g(int a, ...); 16 static void h(int a, ...); 17}; 18 19void g(int a, ...); 20 21void 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 41void 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 76int (^block)(int, ...); 77 78void 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 90class D { 91public: 92 void operator() (int a, ...); 93}; 94 95void 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 109class E { 110 E(int, ...); // expected-note 2{{implicitly declared private here}} 111}; 112 113void 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 131class Foo { 132 public: 133 Foo() {} 134}; 135 136int Helper(...); 137const int size = sizeof(Helper(Foo())); 138 139namespace std { 140 class type_info { }; 141} 142 143struct Base { virtual ~Base(); }; 144Base &get_base(...); 145int eat_base(...); 146 147void 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 162void t6(Foo somearg, ... ) { 163 __builtin_va_list list; 164 __builtin_va_start(list, somearg); 165} 166 167void t7(int n, ...) { 168 __builtin_va_list list; 169 __builtin_va_start(list, n); 170 (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}} 171 __builtin_va_end(list); 172} 173 174struct Abstract { 175 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}} 176}; 177 178void t8(int n, ...) { 179 __builtin_va_list list; 180 __builtin_va_start(list, n); 181 (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}} 182 __builtin_va_end(list); 183} 184 185int t9(int n) { 186 // Make sure the error works in potentially-evaluated sizeof 187 return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); 188#if __cplusplus <= 199711L 189 // expected-warning@-2 {{cannot pass object of non-POD type 'Foo' through variadic function; call will abort at runtime}} 190#endif 191} 192 193// PR14057 194namespace t10 { 195 struct F { 196 F(); 197 }; 198 199 struct S { 200 void operator()(F, ...); 201 }; 202 203 void foo() { 204 S s; 205 F f; 206 s.operator()(f); 207 s(f); 208 } 209} 210 211namespace t11 { 212 typedef void(*function_ptr)(int, ...); 213 typedef void(C::*member_ptr)(int, ...); 214 typedef void(^block_ptr)(int, ...); 215 216 function_ptr get_f_ptr(); 217 member_ptr get_m_ptr(); 218 block_ptr get_b_ptr(); 219 220 function_ptr arr_f_ptr[5]; 221 member_ptr arr_m_ptr[5]; 222 block_ptr arr_b_ptr[5]; 223 224 void test() { 225 C c(10); 226 227 (get_f_ptr())(10, c); 228#if __cplusplus <= 199711L 229 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 230#endif 231 (get_f_ptr())(10, version); 232 233 (c.*get_m_ptr())(10, c); 234#if __cplusplus <= 199711L 235 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} 236#endif 237 (c.*get_m_ptr())(10, version); 238 239 (get_b_ptr())(10, c); 240#if __cplusplus <= 199711L 241 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} 242#endif 243 244 (get_b_ptr())(10, version); 245 246 (arr_f_ptr[3])(10, c); 247#if __cplusplus <= 199711L 248 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 249#endif 250 251 (arr_f_ptr[3])(10, version); 252 253 (c.*arr_m_ptr[3])(10, c); 254#if __cplusplus <= 199711L 255 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} 256#endif 257 258 (c.*arr_m_ptr[3])(10, version); 259 260 (arr_b_ptr[3])(10, c); 261#if __cplusplus <= 199711L 262 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} 263#endif 264 (arr_b_ptr[3])(10, version); 265 } 266} 267