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