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 6extern char version[]; 7 8class C { 9public: 10 C(int); 11 void g(int a, ...); 12 static void h(int a, ...); 13}; 14 15void g(int a, ...); 16 17void 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 29void 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 48int (^block)(int, ...); 49 50void 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 58class D { 59public: 60 void operator() (int a, ...); 61}; 62 63void 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 73class E { 74 E(int, ...); // expected-note 2{{implicitly declared private here}} 75}; 76 77void 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 89class Foo { 90 public: 91 Foo() {} 92}; 93 94int Helper(...); 95const int size = sizeof(Helper(Foo())); 96 97namespace std { 98 class type_info { }; 99} 100 101struct Base { virtual ~Base(); }; 102Base &get_base(...); 103int eat_base(...); 104 105void 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 114void t6(Foo somearg, ... ) { 115 __builtin_va_list list; 116 __builtin_va_start(list, somearg); 117} 118 119void 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 126struct Abstract { 127 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}} 128}; 129 130void 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 137int 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 143namespace t10 { 144 struct F { 145 F(); 146 }; 147 148 struct S { 149 void operator()(F, ...); 150 }; 151 152 void foo() { 153 S s; 154 F f; 155 s.operator()(f); 156 s(f); 157 } 158} 159 160namespace 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 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