202 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s2 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)...) {} // expected-error {{attempt to use a deleted function}}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; // expected-note {{'~deleted_dtor' has been explicitly marked deleted here}}63 };64 65 disable_dtor<deleted_dtor> dd(4, 'x'); // expected-note {{in instantiation of function template specialization 'disabled_dtor::disable_dtor<disabled_dtor::deleted_dtor>::disable_dtor<int, char>' requested here}}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 else89 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 else100 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*() { 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-re {{default constructor of 'Test2<pr16061::X>' is implicitly deleted because variant field 'struct (anonymous struct at{{.+}})' 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<X>'}}146}147 148namespace GH48416 {149 150struct non_trivial_constructor {151 constexpr non_trivial_constructor() : x(100) {}152 int x;153};154 155 156union U1 {157 int a;158 non_trivial_constructor b; // expected-note {{has a non-trivial default constructor}}159};160 161union U2 {162 int a{1000};163 non_trivial_constructor b;164};165 166union U3 {167 int a;168 non_trivial_constructor b{};169};170 171union U4 {172 int a{}; // expected-note {{previous initialization is here}}173 non_trivial_constructor b{}; // expected-error {{initializing multiple members of union}}174};175 176U1 u1; // expected-error {{call to implicitly-deleted default constructor}}177U2 u2;178U3 u3;179U4 u4;180 181static_assert(U2().a == 1000, "");182static_assert(U3().a == 1000, "");183// expected-error@-1 {{static assertion expression is not an integral constant expression}}184// expected-note@-2 {{read of member 'a' of union with active member 'b'}}185static_assert(U2().b.x == 100, "");186// expected-error@-1 {{static assertion expression is not an integral constant expression}}187// expected-note@-2 {{read of member 'b' of union with active member 'a'}}188static_assert(U3().b.x == 100, "");189 190} // namespace GH48416191 192namespace GH81774 {193struct Handle {194 Handle(int) {}195};196// Should be well-formed because NoState has a brace-or-equal-initializer.197union a {198 int NoState = 0;199 Handle CustomState;200} b;201} // namespace GH81774202