Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-error=non-pod-varargs
      2 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs
      3 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs
      4 
      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-compatibility
      7 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++98 %s -Wno-error=non-pod-varargs -fms-compatibility
      8 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -Wno-error=non-pod-varargs -fms-compatibility
      9 
     10 extern char version[];
     11 
     12 class C {
     13 public:
     14   C(int);
     15   void g(int a, ...);
     16   static void h(int a, ...);
     17 };
     18 
     19 void g(int a, ...);
     20 
     21 void t1()
     22 {
     23   C c(10);
     24 
     25   g(10, c);
     26 #if __cplusplus <= 199711L
     27   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
     28 #endif
     29 
     30   g(10, version);
     31 
     32   void (*ptr)(int, ...) = g;
     33   ptr(10, c);
     34 #if __cplusplus <= 199711L
     35   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
     36 #endif
     37 
     38   ptr(10, version);
     39 }
     40 
     41 void t2()
     42 {
     43   C c(10);
     44 
     45   c.g(10, c);
     46 #if __cplusplus <= 199711L
     47   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
     48 #endif
     49 
     50   c.g(10, version);
     51 
     52   void (C::*ptr)(int, ...) = &C::g;
     53   (c.*ptr)(10, c);
     54 #if __cplusplus <= 199711L
     55   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
     56 #endif
     57 
     58   (c.*ptr)(10, version);
     59 
     60   C::h(10, c);
     61 #if __cplusplus <= 199711L
     62   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
     63 #endif
     64 
     65   C::h(10, version);
     66 
     67   void (*static_ptr)(int, ...) = &C::h;
     68   static_ptr(10, c);
     69 #if __cplusplus <= 199711L
     70   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
     71 #endif
     72 
     73   static_ptr(10, version);
     74 }
     75 
     76 int (^block)(int, ...);
     77 
     78 void t3()
     79 {
     80   C c(10);
     81 
     82   block(10, c);
     83 #if __cplusplus <= 199711L
     84   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
     85 #endif
     86 
     87   block(10, version);
     88 }
     89 
     90 class D {
     91 public:
     92   void operator() (int a, ...);
     93 };
     94 
     95 void t4()
     96 {
     97   C c(10);
     98 
     99   D d;
    100 
    101   d(10, c);
    102 #if __cplusplus <= 199711L
    103   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
    104 #endif
    105 
    106   d(10, version);
    107 }
    108 
    109 class E {
    110   E(int, ...); // expected-note 2{{implicitly declared private here}}
    111 };
    112 
    113 void t5()
    114 {
    115   C c(10);
    116 
    117   E e(10, c);
    118 #if __cplusplus <= 199711L
    119   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
    120 #endif
    121   // expected-error@-4 {{calling a private constructor of class 'E'}}
    122   (void)E(10, c);
    123 #if __cplusplus <= 199711L
    124   // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
    125 #endif
    126   // expected-error@-4 {{calling a private constructor of class 'E'}}
    127 
    128 }
    129 
    130 // PR5761: unevaluated operands and the non-POD warning
    131 class Foo {
    132  public:
    133   Foo() {}
    134 };
    135 
    136 int Helper(...);
    137 const int size = sizeof(Helper(Foo()));
    138 
    139 namespace std {
    140   class type_info { };
    141 }
    142 
    143 struct Base { virtual ~Base(); };
    144 Base &get_base(...);
    145 int eat_base(...);
    146 
    147 void test_typeid(Base &base) {
    148   (void)typeid(get_base(base));
    149 #if __cplusplus <= 199711L
    150   // expected-warning@-2 {{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
    151 #else
    152   // expected-warning@-4 {{cannot pass object of non-trivial type 'Base' through variadic function; call will abort at runtime}}
    153 #endif
    154   // expected-warning@-6 {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
    155   (void)typeid(eat_base(base)); // okay
    156 }
    157 
    158 
    159 // rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is
    160 // magic.
    161 
    162 void t6(Foo somearg, ... ) {
    163   __builtin_va_list list;
    164   __builtin_va_start(list, somearg);
    165 }
    166 
    167 void t7(int n, ...) {
    168   __builtin_va_list list;
    169   __builtin_va_start(list, n);
    170   (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}
    171   __builtin_va_end(list);
    172 }
    173 
    174 struct Abstract {
    175   virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}}
    176 };
    177 
    178 void t8(int n, ...) {
    179   __builtin_va_list list;
    180   __builtin_va_start(list, n);
    181   (void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}
    182   __builtin_va_end(list);
    183 }
    184 
    185 int t9(int n) {
    186   // Make sure the error works in potentially-evaluated sizeof
    187   return (int)sizeof(*(Helper(Foo()), (int (*)[n])0));
    188 #if __cplusplus <= 199711L
    189   // expected-warning@-2 {{cannot pass object of non-POD type 'Foo' through variadic function; call will abort at runtime}}
    190 #endif
    191 }
    192 
    193 // PR14057
    194 namespace t10 {
    195   struct F {
    196     F();
    197   };
    198 
    199   struct S {
    200     void operator()(F, ...);
    201   };
    202 
    203   void foo() {
    204     S s;
    205     F f;
    206     s.operator()(f);
    207     s(f);
    208   }
    209 }
    210 
    211 namespace t11 {
    212   typedef void(*function_ptr)(int, ...);
    213   typedef void(C::*member_ptr)(int, ...);
    214   typedef void(^block_ptr)(int, ...);
    215 
    216   function_ptr get_f_ptr();
    217   member_ptr get_m_ptr();
    218   block_ptr get_b_ptr();
    219 
    220   function_ptr arr_f_ptr[5];
    221   member_ptr arr_m_ptr[5];
    222   block_ptr arr_b_ptr[5];
    223 
    224   void test() {
    225     C c(10);
    226 
    227     (get_f_ptr())(10, c);
    228 #if __cplusplus <= 199711L
    229     // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
    230 #endif
    231     (get_f_ptr())(10, version);
    232 
    233     (c.*get_m_ptr())(10, c);
    234 #if __cplusplus <= 199711L
    235     // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
    236 #endif
    237     (c.*get_m_ptr())(10, version);
    238 
    239     (get_b_ptr())(10, c);
    240 #if __cplusplus <= 199711L
    241     // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
    242 #endif
    243 
    244     (get_b_ptr())(10, version);
    245 
    246     (arr_f_ptr[3])(10, c);
    247 #if __cplusplus <= 199711L
    248     // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
    249 #endif
    250 
    251     (arr_f_ptr[3])(10, version);
    252 
    253     (c.*arr_m_ptr[3])(10, c);
    254 #if __cplusplus <= 199711L
    255     // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
    256 #endif
    257 
    258     (c.*arr_m_ptr[3])(10, version);
    259 
    260     (arr_b_ptr[3])(10, c);
    261 #if __cplusplus <= 199711L
    262     // expected-warning@-2 {{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
    263 #endif
    264     (arr_b_ptr[3])(10, version);
    265   }
    266 }
    267