1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs 2 3 extern char version[]; 4 5 class C { 6 public: 7 C(int); 8 void g(int a, ...); 9 static void h(int a, ...); 10 }; 11 12 void g(int a, ...); 13 14 void t1() 15 { 16 C c(10); 17 18 g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 19 g(10, version); 20 21 void (*ptr)(int, ...) = g; 22 ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 23 ptr(10, version); 24 } 25 26 void t2() 27 { 28 C c(10); 29 30 c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} 31 c.g(10, version); 32 33 void (C::*ptr)(int, ...) = &C::g; 34 (c.*ptr)(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} 35 (c.*ptr)(10, version); 36 37 C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 38 C::h(10, version); 39 40 void (*static_ptr)(int, ...) = &C::h; 41 static_ptr(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 42 static_ptr(10, version); 43 } 44 45 int (^block)(int, ...); 46 47 void t3() 48 { 49 C c(10); 50 51 block(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} 52 block(10, version); 53 } 54 55 class D { 56 public: 57 void operator() (int a, ...); 58 }; 59 60 void t4() 61 { 62 C c(10); 63 64 D d; 65 66 d(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} 67 d(10, version); 68 } 69 70 class E { 71 E(int, ...); // expected-note 2{{implicitly declared private here}} 72 }; 73 74 void t5() 75 { 76 C c(10); 77 78 E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \ 79 // expected-error{{calling a private constructor of class 'E'}} 80 (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \ 81 // expected-error{{calling a private constructor of class 'E'}} 82 83 } 84 85 // PR5761: unevaluated operands and the non-POD warning 86 class Foo { 87 public: 88 Foo() {} 89 }; 90 91 int Helper(...); 92 const int size = sizeof(Helper(Foo())); 93 94 namespace std { 95 class type_info { }; 96 } 97 98 struct Base { virtual ~Base(); }; 99 Base &get_base(...); 100 int eat_base(...); 101 102 void test_typeid(Base &base) { 103 (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}} 104 (void)typeid(eat_base(base)); // okay 105 } 106 107 108 // rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is 109 // magic. 110 111 void t6(Foo somearg, ... ) { 112 __builtin_va_list list; 113 __builtin_va_start(list, somearg); 114 } 115 116 void t7(int n, ...) { 117 __builtin_va_list list; 118 __builtin_va_start(list, n); 119 (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}} 120 __builtin_va_end(list); 121 } 122 123 struct Abstract { 124 virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}} 125 }; 126 127 void t8(int n, ...) { 128 __builtin_va_list list; 129 __builtin_va_start(list, n); 130 (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}} 131 __builtin_va_end(list); 132 } 133 134 int t9(int n) { 135 // Make sure the error works in potentially-evaluated sizeof 136 return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); // expected-warning{{cannot pass object of non-POD type}} 137 } 138 139 // PR14057 140 namespace t10 { 141 struct F { 142 F(); 143 }; 144 145 struct S { 146 void operator()(F, ...); 147 }; 148 149 void foo() { 150 S s; 151 F f; 152 s.operator()(f); 153 s(f); 154 } 155 } 156 157 namespace t11 { 158 typedef void(*function_ptr)(int, ...); 159 typedef void(C::*member_ptr)(int, ...); 160 typedef void(^block_ptr)(int, ...); 161 162 function_ptr get_f_ptr(); 163 member_ptr get_m_ptr(); 164 block_ptr get_b_ptr(); 165 166 function_ptr arr_f_ptr[5]; 167 member_ptr arr_m_ptr[5]; 168 block_ptr arr_b_ptr[5]; 169 170 void test() { 171 C c(10); 172 173 (get_f_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 174 (get_f_ptr())(10, version); 175 176 (c.*get_m_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}} 177 (c.*get_m_ptr())(10, version); 178 179 (get_b_ptr())(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} 180 (get_b_ptr())(10, version); 181 182 (arr_f_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}} 183 (arr_f_ptr[3])(10, version); 184 185 (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}} 186 (c.*arr_m_ptr[3])(10, version); 187 188 (arr_b_ptr[3])(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}} 189 (arr_b_ptr[3])(10, version); 190 } 191 } 192