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 Sambucvoid *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