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