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;
u2(int k)16 u2(int k) : k(k) {}
u2()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));
operator new(size_t,void * p)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>
disable_dtor(U &&...u)54 disable_dtor(U &&...u) : val(forward<U>(u)...) {}
~disable_dtor()55 ~disable_dtor() {}
56 };
57
58 struct deleted_dtor {
deleted_dtordisabled_dtor::deleted_dtor59 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
optionaloptional::optional73 optional() : has(false) {}
74 template<typename...U>
optionaloptional::optional75 optional(U &&...u) : has(true), value(forward<U>(u)...) {}
76
optionaloptional::optional77 optional(const optional &o) : has(o.has) {
78 if (has) new (&value) T(o.value);
79 }
optionaloptional::optional80 optional(optional &&o) : has(o.has) {
81 if (has) new (&value) T(move(o.value));
82 }
83
operator =optional::optional84 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 }
operator =optional::optional95 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
~optionaloptional::optional107 ~optional() {
108 if (has)
109 value.~T();
110 }
111
operator booloptional::optional112 explicit operator bool() const { return has; }
operator *optional::optional113 T &operator*() { return value; }
114 };
115
116 optional<non_trivial> o1;
117 optional<non_trivial> o2{non_trivial()};
118 optional<non_trivial> o3{*o2};
f()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-re {{default constructor of 'Test2<pr16061::X>' is implicitly deleted because variant field 'struct (anonymous struct at{{.+}})' 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<X>'}}
146 }
147
148 namespace GH48416 {
149
150 struct non_trivial_constructor {
non_trivial_constructorGH48416::non_trivial_constructor151 constexpr non_trivial_constructor() : x(100) {}
152 int x;
153 };
154
155
156 union U1 {
157 int a;
158 non_trivial_constructor b; // expected-note {{has a non-trivial default constructor}}
159 };
160
161 union U2 {
162 int a{1000};
163 non_trivial_constructor b;
164 };
165
166 union U3 {
167 int a;
168 non_trivial_constructor b{};
169 };
170
171 union U4 {
172 int a{}; // expected-note {{previous initialization is here}}
173 non_trivial_constructor b{}; // expected-error {{initializing multiple members of union}}
174 };
175
176 U1 u1; // expected-error {{call to implicitly-deleted default constructor}}
177 U2 u2;
178 U3 u3;
179 U4 u4;
180
181 static_assert(U2().a == 1000, "");
182 static_assert(U3().a == 1000, "");
183 // expected-error@-1 {{static assertion expression is not an integral constant expression}}
184 // expected-note@-2 {{read of member 'a' of union with active member 'b'}}
185 static_assert(U2().b.x == 100, "");
186 // expected-error@-1 {{static assertion expression is not an integral constant expression}}
187 // expected-note@-2 {{read of member 'b' of union with active member 'a'}}
188 static_assert(U3().b.x == 100, "");
189
190 } // namespace GH48416
191