| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs |
| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs |
| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs |
| |
| // Check that the warning is still there under -fms-compatibility. |
| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs -fms-compatibility |
| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs -fms-compatibility |
| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs -fms-compatibility |
| |
| extern char version[]; |
| |
| class C { |
| public: |
| C(int); |
| void g(int a, ...); |
| static void h(int a, ...); |
| }; |
| |
| void g(int a, ...); |
| |
| void t1() |
| { |
| C c(10); |
| |
| g(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} |
| #endif |
| |
| g(10, version); |
| |
| void (*ptr)(int, ...) = g; |
| ptr(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} |
| #endif |
| |
| ptr(10, version); |
| } |
| |
| void t2() |
| { |
| C c(10); |
| |
| c.g(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} |
| #endif |
| |
| c.g(10, version); |
| |
| void (C::*ptr)(int, ...) = &C::g; |
| (c.*ptr)(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} |
| #endif |
| |
| (c.*ptr)(10, version); |
| |
| C::h(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} |
| #endif |
| |
| C::h(10, version); |
| |
| void (*static_ptr)(int, ...) = &C::h; |
| static_ptr(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} |
| #endif |
| |
| static_ptr(10, version); |
| } |
| |
| int (^block)(int, ...); |
| |
| void t3() |
| { |
| C c(10); |
| |
| block(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} |
| #endif |
| |
| block(10, version); |
| } |
| |
| class D { |
| public: |
| void operator() (int a, ...); |
| }; |
| |
| void t4() |
| { |
| C c(10); |
| |
| D d; |
| |
| d(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} |
| #endif |
| |
| d(10, version); |
| } |
| |
| class E { |
| E(int, ...); // expected-note 2{{implicitly declared private here}} |
| }; |
| |
| void t5() |
| { |
| C c(10); |
| |
| E e(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} |
| #endif |
| // expected-error@-4 {{calling a private constructor of class 'E'}} |
| (void)E(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} |
| #endif |
| // expected-error@-4 {{calling a private constructor of class 'E'}} |
| |
| } |
| |
| // PR5761: unevaluated operands and the non-POD warning |
| class Foo { |
| public: |
| Foo() {} |
| }; |
| |
| int Helper(...); |
| const int size = sizeof(Helper(Foo())); |
| |
| namespace std { |
| class type_info { }; |
| } |
| |
| struct Base { virtual ~Base(); }; |
| Base &get_base(...); |
| int eat_base(...); |
| |
| void test_typeid(Base &base) { |
| (void)typeid(get_base(base)); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}} |
| #else |
| // expected-warning@-4 {{cannot pass object of non-trivial type 'Base' through variadic function; call will abort at runtime}} |
| #endif |
| // expected-warning@-6 {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} |
| (void)typeid(eat_base(base)); // okay |
| } |
| |
| |
| // rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is |
| // magic. |
| |
| void t6(Foo somearg, ... ) { |
| __builtin_va_list list; |
| __builtin_va_start(list, somearg); |
| } |
| |
| void t7(int n, ...) { |
| __builtin_va_list list; |
| __builtin_va_start(list, n); |
| (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}} |
| __builtin_va_end(list); |
| } |
| |
| struct Abstract { |
| virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}} |
| }; |
| |
| void t8(int n, ...) { |
| __builtin_va_list list; |
| __builtin_va_start(list, n); |
| (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}} |
| __builtin_va_end(list); |
| } |
| |
| int t9(int n) { |
| // Make sure the error works in potentially-evaluated sizeof |
| return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'Foo' through variadic function; call will abort at runtime}} |
| #endif |
| } |
| |
| // PR14057 |
| namespace t10 { |
| struct F { |
| F(); |
| }; |
| |
| struct S { |
| void operator()(F, ...); |
| }; |
| |
| void foo() { |
| S s; |
| F f; |
| s.operator()(f); |
| s(f); |
| } |
| } |
| |
| namespace t11 { |
| typedef void(*function_ptr)(int, ...); |
| typedef void(C::*member_ptr)(int, ...); |
| typedef void(^block_ptr)(int, ...); |
| |
| function_ptr get_f_ptr(); |
| member_ptr get_m_ptr(); |
| block_ptr get_b_ptr(); |
| |
| function_ptr arr_f_ptr[5]; |
| member_ptr arr_m_ptr[5]; |
| block_ptr arr_b_ptr[5]; |
| |
| void test() { |
| C c(10); |
| |
| (get_f_ptr())(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} |
| #endif |
| (get_f_ptr())(10, version); |
| |
| (c.*get_m_ptr())(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} |
| #endif |
| (c.*get_m_ptr())(10, version); |
| |
| (get_b_ptr())(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} |
| #endif |
| |
| (get_b_ptr())(10, version); |
| |
| (arr_f_ptr[3])(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} |
| #endif |
| |
| (arr_f_ptr[3])(10, version); |
| |
| (c.*arr_m_ptr[3])(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} |
| #endif |
| |
| (c.*arr_m_ptr[3])(10, version); |
| |
| (arr_b_ptr[3])(10, c); |
| #if __cplusplus <= 199711L |
| // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} |
| #endif |
| (arr_b_ptr[3])(10, version); |
| } |
| } |