vararg-non-pod.cpp revision 55693fbe18e9431dbb0ea9e20d140d8bc6bc4c72
1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wnon-pod-varargs
2
3extern char version[];
4
5class C {
6public:
7  C(int);
8  void g(int a, ...);
9  static void h(int a, ...);
10};
11
12void g(int a, ...);
13
14void 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
22void t2()
23{
24  C c(10);
25
26  c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
27  c.g(10, version);
28
29  C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
30  C::h(10, version);
31}
32
33int (^block)(int, ...);
34
35void t3()
36{
37  C c(10);
38
39  block(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
40  block(10, version);
41}
42
43class D {
44public:
45  void operator() (int a, ...);
46};
47
48void t4()
49{
50  C c(10);
51
52  D d;
53
54  d(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
55  d(10, version);
56}
57
58class E {
59  E(int, ...); // expected-note 2{{implicitly declared private here}}
60};
61
62void t5()
63{
64  C c(10);
65
66  E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \
67    // expected-error{{calling a private constructor of class 'E'}}
68  (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}} \
69    // expected-error{{calling a private constructor of class 'E'}}
70
71}
72
73// PR5761: unevaluated operands and the non-POD warning
74class Foo {
75 public:
76  Foo() {}
77};
78
79int Helper(...);
80const int size = sizeof(Helper(Foo()));
81
82namespace std {
83  class type_info { };
84}
85
86struct Base { virtual ~Base(); };
87Base &get_base(...);
88int eat_base(...);
89
90void test_typeid(Base &base) {
91  (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
92  (void)typeid(eat_base(base)); // okay
93}
94
95
96// rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is
97// magic.
98
99void t6(Foo somearg, ... ) {
100  __builtin_va_list list;
101  __builtin_va_start(list, somearg);
102}
103
104void t7(int n, ...) {
105  __builtin_va_list list;
106  __builtin_va_start(list, n);
107  (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}
108  __builtin_va_end(list);
109}
110
111struct Abstract {
112  virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}}
113};
114
115void t8(int n, ...) {
116  __builtin_va_list list;
117  __builtin_va_start(list, n);
118  (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}
119  __builtin_va_end(list);
120}
121