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