blob: 0e4add84955e9ded77a10c908043249fabfcbccb [file] [log] [blame]
Richard Smith762bb9d2011-10-13 22:29:44 +00001// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
Sean Huntcf34e752011-05-16 22:41:40 +00002
3struct non_trivial {
4 non_trivial();
5 non_trivial(const non_trivial&);
6 non_trivial& operator = (const non_trivial&);
7 ~non_trivial();
8};
9
10union u {
11 non_trivial nt;
12};
Richard Smithec92bc72012-03-03 23:51:05 +000013union u2 {
14 non_trivial nt;
15 int k;
16 u2(int k) : k(k) {}
17 u2() : nt() {}
18};
Sean Huntcf34e752011-05-16 22:41:40 +000019
Richard Smithb9c64d82012-02-16 20:41:22 +000020union static_data_member {
21 static int i;
22};
23int static_data_member::i;
24
Sean Huntcf34e752011-05-16 22:41:40 +000025union bad {
Richard Smithb9c64d82012-02-16 20:41:22 +000026 int &i; // expected-error {{union member 'i' has reference type 'int &'}}
Sean Huntcf34e752011-05-16 22:41:40 +000027};
28
29struct s {
30 union {
31 non_trivial nt;
32 };
33};
Richard Smithea7c1e22012-02-26 10:50:32 +000034
35// Don't crash on this.
36struct TemplateCtor { template<typename T> TemplateCtor(T); };
37union TemplateCtorMember { TemplateCtor s; };
Richard Smithec92bc72012-03-03 23:51:05 +000038
39template<typename T> struct remove_ref { typedef T type; };
40template<typename T> struct remove_ref<T&> { typedef T type; };
41template<typename T> struct remove_ref<T&&> { typedef T type; };
42template<typename T> T &&forward(typename remove_ref<T>::type &&t);
43template<typename T> T &&forward(typename remove_ref<T>::type &t);
44template<typename T> typename remove_ref<T>::type &&move(T &&t);
45
46using size_t = decltype(sizeof(int));
47void *operator new(size_t, void *p) noexcept { return p; }
48
49namespace 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
68namespace 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}