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