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 10 extern char version[]; 11 12 class C { 13 public: test(A a,B b,C c,D d,E e,F f)14 C(int); 15 void g(int a, ...); 16 static void h(int a, ...); 17 }; 18 19 void g(int a, ...); 20 21 void 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 41 void 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 76 int (^block)(int, ...); 77 78 void 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 90 class D { 91 public: 92 void operator() (int a, ...); 93 }; 94 95 void 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 109 class E { 110 E(int, ...); // expected-note 2{{implicitly declared private here}} 111 }; 112 113 void 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 131 class Foo { 132 public: 133 Foo() {} 134 }; 135 136 int Helper(...); 137 const int size = sizeof(Helper(Foo())); 138 139 namespace std { 140 class type_info { }; 141 } 142 143 struct Base { virtual ~Base(); }; 144 Base &get_base(...); 145 int eat_base(...); 146 147 void 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 162 void t6(Foo somearg, ... ) { 163 __builtin_va_list list; 164 __builtin_va_start(list, somearg); 165 } 166 167 void 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 174 struct Abstract { 175 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}} 176 }; 177 178 void 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 185 int 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 194 namespace 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 211 namespace 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