Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
      2 
      3 struct non_trivial {
      4   non_trivial();
      5   non_trivial(const non_trivial&);
      6   non_trivial& operator = (const non_trivial&);
      7   ~non_trivial();
      8 };
      9 
     10 union u {
     11   non_trivial nt;
     12 };
     13 union u2 {
     14   non_trivial nt;
     15   int k;
     16   u2(int k) : k(k) {}
     17   u2() : nt() {}
     18 };
     19 
     20 union static_data_member {
     21   static int i;
     22 };
     23 int static_data_member::i;
     24 
     25 union bad {
     26   int &i; // expected-error {{union member 'i' has reference type 'int &'}}
     27 };
     28 
     29 struct s {
     30   union {
     31     non_trivial nt;
     32   };
     33 };
     34 
     35 // Don't crash on this.
     36 struct TemplateCtor { template<typename T> TemplateCtor(T); };
     37 union TemplateCtorMember { TemplateCtor s; };
     38 
     39 template<typename T> struct remove_ref { typedef T type; };
     40 template<typename T> struct remove_ref<T&> { typedef T type; };
     41 template<typename T> struct remove_ref<T&&> { typedef T type; };
     42 template<typename T> T &&forward(typename remove_ref<T>::type &&t);
     43 template<typename T> T &&forward(typename remove_ref<T>::type &t);
     44 template<typename T> typename remove_ref<T>::type &&move(T &&t);
     45 
     46 using size_t = decltype(sizeof(int));
     47 void *operator new(size_t, void *p) noexcept { return p; }
     48 
     49 namespace disabled_dtor {
     50   template<typename T>
     51   union disable_dtor {
     52     T val;
     53     template<typename...U>
     54     disable_dtor(U &&...u) : val(forward<U>(u)...) {}
     55     ~disable_dtor() {}
     56   };
     57 
     58   struct deleted_dtor {
     59     deleted_dtor(int n, char c) : n(n), c(c) {}
     60     int n;
     61     char c;
     62     ~deleted_dtor() = delete;
     63   };
     64 
     65   disable_dtor<deleted_dtor> dd(4, 'x');
     66 }
     67 
     68 namespace optional {
     69   template<typename T> struct optional {
     70     bool has;
     71     union { T value; };
     72 
     73     optional() : has(false) {}
     74     template<typename...U>
     75     optional(U &&...u) : has(true), value(forward<U>(u)...) {}
     76 
     77     optional(const optional &o) : has(o.has) {
     78       if (has) new (&value) T(o.value);
     79     }
     80     optional(optional &&o) : has(o.has) {
     81       if (has) new (&value) T(move(o.value));
     82     }
     83 
     84     optional &operator=(const optional &o) {
     85       if (has) {
     86         if (o.has)
     87           value = o.value;
     88         else
     89           value.~T();
     90       } else if (o.has) {
     91         new (&value) T(o.value);
     92       }
     93       has = o.has;
     94     }
     95     optional &operator=(optional &&o) {
     96       if (has) {
     97         if (o.has)
     98           value = move(o.value);
     99         else
    100           value.~T();
    101       } else if (o.has) {
    102         new (&value) T(move(o.value));
    103       }
    104       has = o.has;
    105     }
    106 
    107     ~optional() {
    108       if (has)
    109         value.~T();
    110     }
    111 
    112     explicit operator bool() const { return has; }
    113     T &operator*() const { return value; }
    114   };
    115 
    116   optional<non_trivial> o1;
    117   optional<non_trivial> o2{non_trivial()};
    118   optional<non_trivial> o3{*o2};
    119   void f() {
    120     if (o2)
    121       o1 = o2;
    122     o2 = optional<non_trivial>();
    123   }
    124 }
    125 
    126 namespace pr16061 {
    127   struct X { X(); };
    128 
    129   template<typename T> struct Test1 {
    130     union {
    131       struct {
    132         X x;
    133       };
    134     };
    135   };
    136 
    137   template<typename T> struct Test2 {
    138     union {
    139       struct {  // expected-note {{default constructor of 'Test2<pr16061::X>' is implicitly deleted because variant field '' has a non-trivial default constructor}}
    140         T x;
    141       };
    142     };
    143   };
    144 
    145   Test2<X> t2x;  // expected-error {{call to implicitly-deleted default constructor of 'Test2<pr16061::X>'}}
    146 }
    147