273 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs2// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++98 %s -Wno-error=non-pod-varargs3// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-error=non-pod-varargs4 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-compatibility7// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++98 %s -Wno-error=non-pod-varargs -fms-compatibility8// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-error=non-pod-varargs -fms-compatibility9 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 <= 199711L27 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}28#endif29 30 g(10, version);31 32 void (*ptr)(int, ...) = g;33 ptr(10, c);34#if __cplusplus <= 199711L35 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}36#endif37 38 ptr(10, version);39}40 41void t2()42{43 C c(10);44 45 c.g(10, c);46#if __cplusplus <= 199711L47 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}48#endif49 50 c.g(10, version);51 52 void (C::*ptr)(int, ...) = &C::g;53 (c.*ptr)(10, c);54#if __cplusplus <= 199711L55 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}56#endif57 58 (c.*ptr)(10, version);59 60 C::h(10, c);61#if __cplusplus <= 199711L62 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}63#endif64 65 C::h(10, version);66 67 void (*static_ptr)(int, ...) = &C::h;68 static_ptr(10, c);69#if __cplusplus <= 199711L70 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}71#endif72 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 <= 199711L84 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}85#endif86 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 <= 199711L103 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}104#endif105 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 <= 199711L119 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}120#endif121 // expected-error@-4 {{calling a private constructor of class 'E'}}122 (void)E(10, c);123#if __cplusplus <= 199711L124 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}125#endif126 // expected-error@-4 {{calling a private constructor of class 'E'}}127 128}129 130// PR5761: unevaluated operands and the non-POD warning131class 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 <= 199711L150 // expected-warning@-2 {{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}151#else152 // expected-warning@-4 {{cannot pass object of non-trivial type 'Base' through variadic function; call will abort at runtime}}153#endif154 // expected-warning@-6 {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}155 (void)typeid(eat_base(base)); // okay156}157 158 159// Shouldn't warn, doesn't actually use __builtin_va_start is magic.160 161void t6(Foo somearg, ... ) {162 __builtin_va_list list;163 __builtin_va_start(list, somearg);164}165 166// __builtin_stdarg_start is a compatibility alias for __builtin_va_start,167// it should behave the same168void t6b(Foo somearg, ... ) {169 __builtin_va_list list;170 __builtin_stdarg_start(list, somearg); // second argument to 'va_start' is not the last non-variadic parameter [-Wvarargs]171}172 173void t7(int n, ...) {174 __builtin_va_list list;175 __builtin_va_start(list, n);176 (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}177 __builtin_va_end(list);178}179 180struct Abstract {181 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}}182};183 184void t8(int n, ...) {185 __builtin_va_list list;186 __builtin_va_start(list, n);187 (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}188 __builtin_va_end(list);189}190 191int t9(int n) {192 // Make sure the error works in potentially-evaluated sizeof193 return (int)sizeof(*(Helper(Foo()), (int (*)[n])0));194#if __cplusplus <= 199711L195 // expected-warning@-2 {{cannot pass object of non-POD type 'Foo' through variadic function; call will abort at runtime}}196#endif197}198 199// PR14057200namespace t10 {201 struct F {202 F();203 };204 205 struct S {206 void operator()(F, ...);207 };208 209 void foo() {210 S s;211 F f;212 s.operator()(f);213 s(f);214 }215}216 217namespace t11 {218 typedef void(*function_ptr)(int, ...);219 typedef void(C::*member_ptr)(int, ...);220 typedef void(^block_ptr)(int, ...);221 222 function_ptr get_f_ptr();223 member_ptr get_m_ptr();224 block_ptr get_b_ptr();225 226 function_ptr arr_f_ptr[5];227 member_ptr arr_m_ptr[5];228 block_ptr arr_b_ptr[5];229 230 void test() {231 C c(10);232 233 (get_f_ptr())(10, c);234#if __cplusplus <= 199711L235 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}236#endif237 (get_f_ptr())(10, version);238 239 (c.*get_m_ptr())(10, c);240#if __cplusplus <= 199711L241 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}242#endif243 (c.*get_m_ptr())(10, version);244 245 (get_b_ptr())(10, c);246#if __cplusplus <= 199711L247 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}248#endif249 250 (get_b_ptr())(10, version);251 252 (arr_f_ptr[3])(10, c);253#if __cplusplus <= 199711L254 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}255#endif256 257 (arr_f_ptr[3])(10, version);258 259 (c.*arr_m_ptr[3])(10, c);260#if __cplusplus <= 199711L261 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}262#endif263 264 (c.*arr_m_ptr[3])(10, version);265 266 (arr_b_ptr[3])(10, c);267#if __cplusplus <= 199711L268 // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}269#endif270 (arr_b_ptr[3])(10, version);271 }272}273