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