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)47void *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*() const { 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 {{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