Home | History | Annotate | Download | only in class.copy
      1 // RUN: %clang_cc1 -verify %s -std=c++11
      2 
      3 struct Trivial {};
      4 
      5 template<typename T> struct CopyAssign {
      6   static T t;
      7   void test() {
      8     t = t; // expected-error +{{deleted}}
      9   }
     10 };
     11 template<typename T> struct MoveAssign {
     12   static T t;
     13   void test() {
     14     // Overload resolution will ignore a defaulted, deleted move assignment,
     15     // so check for it in a different way.
     16     T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}}
     17   }
     18 };
     19 template<typename T> struct MoveOrCopyAssign {
     20   static T t;
     21   void test() {
     22     t = static_cast<T&&>(t); // expected-error +{{copy assignment operator is implicitly deleted}}
     23   }
     24 };
     25 
     26 struct NonTrivialCopyAssign {
     27   NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
     28 };
     29 struct NonTrivialMoveAssign {
     30   NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
     31 };
     32 struct AmbiguousCopyAssign {
     33   AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile;
     34   AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const;
     35 };
     36 struct AmbiguousMoveAssign {
     37   AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&);
     38   AmbiguousMoveAssign &operator=(volatile AmbiguousMoveAssign &&);
     39 };
     40 struct DeletedCopyAssign {
     41   DeletedCopyAssign &operator=(const DeletedCopyAssign &) = delete; // expected-note 2{{deleted}}
     42 };
     43 struct DeletedMoveAssign {
     44   DeletedMoveAssign &operator=(DeletedMoveAssign &&) = delete; // expected-note 2{{deleted}}
     45 };
     46 class InaccessibleCopyAssign {
     47   InaccessibleCopyAssign &operator=(const InaccessibleCopyAssign &);
     48 };
     49 class InaccessibleMoveAssign {
     50   InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&);
     51 };
     52 class NonConstCopyAssign {
     53   NonConstCopyAssign &operator=(NonConstCopyAssign &);
     54 };
     55 
     56 // A defaulted copy/move assignment operator for class X is defined as deleted
     57 // if X has:
     58 
     59 //   -- a variant member with a non-trivial corresponding assignment operator
     60 //      and X is a union-like class
     61 struct A1 {
     62   union {
     63     NonTrivialCopyAssign x; // expected-note {{variant field 'x' has a non-trivial copy assign}}
     64   };
     65 };
     66 template struct CopyAssign<A1>; // expected-note {{here}}
     67 
     68 struct A2 {
     69   A2 &operator=(A2 &&) = default; // expected-note {{here}}
     70   union {
     71     NonTrivialMoveAssign x; // expected-note {{variant field 'x' has a non-trivial move assign}}
     72   };
     73 };
     74 template struct MoveAssign<A2>; // expected-note {{here}}
     75 
     76 //   -- a non-static const data member of (array of) non-class type
     77 struct B1 {
     78   const int a; // expected-note 2{{field 'a' is of const-qualified type}}
     79 };
     80 struct B2 {
     81   const void *const a[3][9][2]; // expected-note 2{{field 'a' is of const-qualified type 'const void *const [3][9][2]'}}
     82 };
     83 struct B3 {
     84   const void *a[3];
     85 };
     86 template struct CopyAssign<B1>; // expected-note {{here}}
     87 template struct MoveAssign<B1>; // expected-note {{here}}
     88 template struct CopyAssign<B2>; // expected-note {{here}}
     89 template struct MoveAssign<B2>; // expected-note {{here}}
     90 template struct CopyAssign<B3>;
     91 template struct MoveAssign<B3>;
     92 
     93 //   -- a non-static data member of reference type
     94 struct C1 {
     95   int &a; // expected-note 2{{field 'a' is of reference type 'int &'}}
     96 };
     97 template struct CopyAssign<C1>; // expected-note {{here}}
     98 template struct MoveAssign<C1>; // expected-note {{here}}
     99 
    100 //   -- a non-static data member of class type M that cannot be copied/moved
    101 struct D1 {
    102   AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}}
    103 };
    104 struct D2 {
    105   D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
    106   AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}}
    107 };
    108 struct D3 {
    109   DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}}
    110 };
    111 struct D4 {
    112   D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
    113   DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}}
    114 };
    115 struct D5 {
    116   InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible copy}}
    117 };
    118 struct D6 {
    119   D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
    120   InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}}
    121 };
    122 struct D7 {
    123   const Trivial a; // expected-note 3{{field 'a' has no }}
    124 };
    125 struct D8 {
    126   volatile Trivial a; // expected-note 3{{field 'a' has no }}
    127 };
    128 template struct CopyAssign<D1>; // expected-note {{here}}
    129 template struct MoveAssign<D2>; // expected-note {{here}}
    130 template struct MoveOrCopyAssign<D2>; // expected-note {{here}}
    131 template struct CopyAssign<D3>; // expected-note {{here}}
    132 template struct MoveAssign<D4>; // expected-note {{here}}
    133 template struct MoveOrCopyAssign<D4>; // expected-note {{here}}
    134 template struct CopyAssign<D5>; // expected-note {{here}}
    135 template struct MoveAssign<D6>; // expected-note {{here}}
    136 template struct MoveOrCopyAssign<D6>; // expected-note {{here}}
    137 template struct CopyAssign<D7>; // expected-note {{here}}
    138 template struct MoveAssign<D7>; // expected-note {{here}}
    139 template struct MoveOrCopyAssign<D7>; // expected-note {{here}}
    140 template struct CopyAssign<D8>; // expected-note {{here}}
    141 template struct MoveAssign<D8>; // expected-note {{here}}
    142 template struct MoveOrCopyAssign<D8>; // expected-note {{here}}
    143 
    144 //   -- a direct or virtual base that cannot be copied/moved
    145 struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}}
    146 struct E2 : AmbiguousMoveAssign { // expected-note {{base class 'AmbiguousMoveAssign' has multiple move}}
    147   E2 &operator=(E2 &&) = default; // expected-note {{here}}
    148 };
    149 struct E3 : DeletedCopyAssign {}; // expected-note {{base class 'DeletedCopyAssign' has a deleted copy}}
    150 struct E4 : DeletedMoveAssign { // expected-note {{base class 'DeletedMoveAssign' has a deleted move}}
    151   E4 &operator=(E4 &&) = default; // expected-note {{here}}
    152 };
    153 struct E5 : InaccessibleCopyAssign {}; // expected-note {{base class 'InaccessibleCopyAssign' has an inaccessible copy}}
    154 struct E6 : InaccessibleMoveAssign { // expected-note {{base class 'InaccessibleMoveAssign' has an inaccessible move}}
    155   E6 &operator=(E6 &&) = default; // expected-note {{here}}
    156 };
    157 template struct CopyAssign<E1>; // expected-note {{here}}
    158 template struct MoveAssign<E2>; // expected-note {{here}}
    159 template struct CopyAssign<E3>; // expected-note {{here}}
    160 template struct MoveAssign<E4>; // expected-note {{here}}
    161 template struct CopyAssign<E5>; // expected-note {{here}}
    162 template struct MoveAssign<E6>; // expected-note {{here}}
    163 
    164 namespace PR13381 {
    165   struct S {
    166     S &operator=(const S&);
    167     S &operator=(const volatile S&) volatile = delete; // expected-note{{deleted here}}
    168   };
    169   struct T {
    170     volatile S s; // expected-note{{field 's' has a deleted copy assignment}}
    171   };
    172   void g() {
    173     T t;
    174     t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}}
    175   }
    176 }
    177 
    178 namespace Mutable {
    179   struct AmbiguousCopyAssign {
    180     AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &);
    181     AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &);
    182   };
    183   struct X {
    184     AmbiguousCopyAssign a;
    185   };
    186   struct Y {
    187     mutable AmbiguousCopyAssign a; // expected-note {{multiple copy assignment operators}}
    188   };
    189 }
    190 template struct CopyAssign<Mutable::X>;
    191 template struct CopyAssign<Mutable::Y>; // expected-note {{here}}
    192