reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s

struct non_trivial {
  non_trivial();
  non_trivial(const non_trivial&);
  non_trivial& operator = (const non_trivial&);
  ~non_trivial();
};

union u {
  non_trivial nt;
};
union u2 {
  non_trivial nt;
  int k;
  u2(int k) : k(k) {}
  u2() : nt() {}
};

union static_data_member {
  static int i;
};
int static_data_member::i;

union bad {
  int &i; // expected-error {{union member 'i' has reference type 'int &'}}
};

struct s {
  union {
    non_trivial nt;
  };
};

// Don't crash on this.
struct TemplateCtor { template<typename T> TemplateCtor(T); };
union TemplateCtorMember { TemplateCtor s; };

template<typename T> struct remove_ref { typedef T type; };
template<typename T> struct remove_ref<T&> { typedef T type; };
template<typename T> struct remove_ref<T&&> { typedef T type; };
template<typename T> T &&forward(typename remove_ref<T>::type &&t);
template<typename T> T &&forward(typename remove_ref<T>::type &t);
template<typename T> typename remove_ref<T>::type &&move(T &&t);

using size_t = decltype(sizeof(int));
void *operator new(size_t, void *p) noexcept { return p; }

namespace disabled_dtor {
  template<typename T>
  union disable_dtor {
    T val;
    template<typename...U>
    disable_dtor(U &&...u) : val(forward<U>(u)...) {}
    ~disable_dtor() {}
  };

  struct deleted_dtor {
    deleted_dtor(int n, char c) : n(n), c(c) {}
    int n;
    char c;
    ~deleted_dtor() = delete;
  };

  disable_dtor<deleted_dtor> dd(4, 'x');
}

namespace optional {
  template<typename T> struct optional {
    bool has;
    union { T value; };

    optional() : has(false) {}
    template<typename...U>
    optional(U &&...u) : has(true), value(forward<U>(u)...) {}

    optional(const optional &o) : has(o.has) {
      if (has) new (&value) T(o.value);
    }
    optional(optional &&o) : has(o.has) {
      if (has) new (&value) T(move(o.value));
    }

    optional &operator=(const optional &o) {
      if (has) {
        if (o.has)
          value = o.value;
        else
          value.~T();
      } else if (o.has) {
        new (&value) T(o.value);
      }
      has = o.has;
    }
    optional &operator=(optional &&o) {
      if (has) {
        if (o.has)
          value = move(o.value);
        else
          value.~T();
      } else if (o.has) {
        new (&value) T(move(o.value));
      }
      has = o.has;
    }

    ~optional() {
      if (has)
        value.~T();
    }

    explicit operator bool() const { return has; }
    T &operator*() { return value; }
  };

  optional<non_trivial> o1;
  optional<non_trivial> o2{non_trivial()};
  optional<non_trivial> o3{*o2};
  void f() {
    if (o2)
      o1 = o2;
    o2 = optional<non_trivial>();
  }
}

namespace pr16061 {
  struct X { X(); };

  template<typename T> struct Test1 {
    union {
      struct {
        X x;
      };
    };
  };

  template<typename T> struct Test2 {
    union {
      struct {  // expected-note {{default constructor of 'Test2<pr16061::X>' is implicitly deleted because variant field '' has a non-trivial default constructor}}
        T x;
      };
    };
  };

  Test2<X> t2x;  // expected-error {{call to implicitly-deleted default constructor of 'Test2<pr16061::X>'}}
}