1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 2 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}; 13union u2 { 14 non_trivial nt; 15 int k; 16 u2(int k) : k(k) {} 17 u2() : nt() {} 18}; 19 20union static_data_member { 21 static int i; 22}; 23int static_data_member::i; 24 25union bad { 26 int &i; // expected-error {{union member 'i' has reference type 'int &'}} 27}; 28 29struct s { 30 union { 31 non_trivial nt; 32 }; 33}; 34 35// Don't crash on this. 36struct TemplateCtor { template<typename T> TemplateCtor(T); }; 37union TemplateCtorMember { TemplateCtor s; }; 38 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} 125 126namespace 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