Home | History | Annotate | Download | only in SemaCXX
      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