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