189a1d03eSRichard // RUN: %check_clang_tidy %s modernize-use-equals-default %t -- \
2e8a3ddafSNathan James // RUN: -config="{CheckOptions: {modernize-use-equals-default.IgnoreMacros: false}}" \
389a1d03eSRichard // RUN: -- -fno-delayed-template-parsing -fexceptions
489a1d03eSRichard
589a1d03eSRichard // Out of line definition.
689a1d03eSRichard struct OL {
789a1d03eSRichard OL(const OL &);
889a1d03eSRichard OL &operator=(const OL &);
989a1d03eSRichard int Field;
1089a1d03eSRichard };
OL(const OL & Other)1189a1d03eSRichard OL::OL(const OL &Other) : Field(Other.Field) {}
1289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial copy constructor [modernize-use-equals-default]
1389a1d03eSRichard // CHECK-FIXES: OL::OL(const OL &Other) = default;
operator =(const OL & Other)1489a1d03eSRichard OL &OL::operator=(const OL &Other) {
1589a1d03eSRichard Field = Other.Field;
1689a1d03eSRichard return *this;
1789a1d03eSRichard }
1889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:9: warning: use '= default' to define a trivial copy-assignment operator [modernize-use-equals-default]
1989a1d03eSRichard // CHECK-FIXES: OL &OL::operator=(const OL &Other) = default;
2089a1d03eSRichard
2189a1d03eSRichard // Inline.
2289a1d03eSRichard struct IL {
ILIL2389a1d03eSRichard IL(const IL &Other) : Field(Other.Field) {}
2489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
2589a1d03eSRichard // CHECK-FIXES: IL(const IL &Other) = default;
operator =IL2689a1d03eSRichard IL &operator=(const IL &Other) {
2789a1d03eSRichard Field = Other.Field;
2889a1d03eSRichard return *this;
2989a1d03eSRichard }
3089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-4]]:7: warning: use '= default'
3189a1d03eSRichard // CHECK-FIXES: IL &operator=(const IL &Other) = default;
3289a1d03eSRichard int Field;
3389a1d03eSRichard };
3489a1d03eSRichard
35083e3a17SAlexander Shaposhnikov // Skip unions.
36083e3a17SAlexander Shaposhnikov union NU {
NU(const NU & Other)37083e3a17SAlexander Shaposhnikov NU(const NU &Other) : Field(Other.Field) {}
38083e3a17SAlexander Shaposhnikov // CHECK-FIXES: NU(const NU &Other) :
operator =(const NU & Other)39083e3a17SAlexander Shaposhnikov NU &operator=(const NU &Other) {
40083e3a17SAlexander Shaposhnikov Field = Other.Field;
41083e3a17SAlexander Shaposhnikov return *this;
42083e3a17SAlexander Shaposhnikov }
43083e3a17SAlexander Shaposhnikov // CHECK-FIXES: NU &operator=(const NU &Other) {
44083e3a17SAlexander Shaposhnikov IL Field;
45083e3a17SAlexander Shaposhnikov };
46083e3a17SAlexander Shaposhnikov
4744503482SAlexander Shaposhnikov // Skip structs/classes containing anonymous unions.
4844503482SAlexander Shaposhnikov struct SU {
SUSU4944503482SAlexander Shaposhnikov SU(const SU &Other) : Field(Other.Field) {}
5044503482SAlexander Shaposhnikov // CHECK-FIXES: SU(const SU &Other) :
operator =SU5144503482SAlexander Shaposhnikov SU &operator=(const SU &Other) {
5244503482SAlexander Shaposhnikov Field = Other.Field;
5344503482SAlexander Shaposhnikov return *this;
5444503482SAlexander Shaposhnikov }
5544503482SAlexander Shaposhnikov // CHECK-FIXES: SU &operator=(const SU &Other) {
5644503482SAlexander Shaposhnikov union {
5744503482SAlexander Shaposhnikov IL Field;
5844503482SAlexander Shaposhnikov };
5944503482SAlexander Shaposhnikov };
6044503482SAlexander Shaposhnikov
6189a1d03eSRichard // Wrong type.
6289a1d03eSRichard struct WT {
WTWT6389a1d03eSRichard WT(const IL &Other) {}
6489a1d03eSRichard WT &operator=(const IL &);
6589a1d03eSRichard };
operator =(const IL & Other)6689a1d03eSRichard WT &WT::operator=(const IL &Other) { return *this; }
6789a1d03eSRichard
6889a1d03eSRichard // Qualifiers.
6989a1d03eSRichard struct Qual {
QualQual7089a1d03eSRichard Qual(const Qual &Other) : Field(Other.Field), Volatile(Other.Volatile),
7189a1d03eSRichard Mutable(Other.Mutable), Reference(Other.Reference),
7289a1d03eSRichard Const(Other.Const) {}
7389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
7489a1d03eSRichard // CHECK-FIXES: Qual(const Qual &Other)
7589a1d03eSRichard // CHECK-FIXES: = default;
7689a1d03eSRichard
7789a1d03eSRichard int Field;
7889a1d03eSRichard volatile char Volatile;
7989a1d03eSRichard mutable bool Mutable;
8089a1d03eSRichard const OL &Reference; // This makes this class non-assignable.
8189a1d03eSRichard const IL Const; // This also makes this class non-assignable.
8289a1d03eSRichard static int Static;
8389a1d03eSRichard };
8489a1d03eSRichard
8589a1d03eSRichard // Wrong init arguments.
8689a1d03eSRichard struct WI {
WIWI8789a1d03eSRichard WI(const WI &Other) : Field1(Other.Field1), Field2(Other.Field1) {}
8889a1d03eSRichard WI &operator=(const WI &);
8989a1d03eSRichard int Field1, Field2;
9089a1d03eSRichard };
operator =(const WI & Other)9189a1d03eSRichard WI &WI::operator=(const WI &Other) {
9289a1d03eSRichard Field1 = Other.Field1;
9389a1d03eSRichard Field2 = Other.Field1;
9489a1d03eSRichard return *this;
9589a1d03eSRichard }
9689a1d03eSRichard
9789a1d03eSRichard // Missing field.
9889a1d03eSRichard struct MF {
MFMF9989a1d03eSRichard MF(const MF &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
10089a1d03eSRichard MF &operator=(const MF &);
10189a1d03eSRichard int Field1, Field2, Field3;
10289a1d03eSRichard };
operator =(const MF & Other)10389a1d03eSRichard MF &MF::operator=(const MF &Other) {
10489a1d03eSRichard Field1 = Other.Field1;
10589a1d03eSRichard Field2 = Other.Field2;
10689a1d03eSRichard return *this;
10789a1d03eSRichard }
10889a1d03eSRichard
10989a1d03eSRichard struct Comments {
CommentsComments11089a1d03eSRichard Comments(const Comments &Other)
11189a1d03eSRichard /* don't delete */ : /* this comment */ Field(Other.Field) {}
11289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
11389a1d03eSRichard // CHECK-FIXES: /* don't delete */ = default;
11489a1d03eSRichard int Field;
11589a1d03eSRichard };
11689a1d03eSRichard
11789a1d03eSRichard struct MoreComments {
MoreCommentsMoreComments11889a1d03eSRichard MoreComments(const MoreComments &Other) /* this comment is OK */
11989a1d03eSRichard : Field(Other.Field) {}
12089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
12189a1d03eSRichard // CHECK-FIXES: MoreComments(const MoreComments &Other) /* this comment is OK */
12289a1d03eSRichard // CHECK-FIXES-NEXT: = default;
12389a1d03eSRichard int Field;
12489a1d03eSRichard };
12589a1d03eSRichard
12689a1d03eSRichard struct ColonInComment {
ColonInCommentColonInComment12789a1d03eSRichard ColonInComment(const ColonInComment &Other) /* : */ : Field(Other.Field) {}
12889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
12989a1d03eSRichard // CHECK-FIXES: ColonInComment(const ColonInComment &Other) /* : */ = default;
13089a1d03eSRichard int Field;
13189a1d03eSRichard };
13289a1d03eSRichard
13389a1d03eSRichard // No members or bases (in particular, no colon).
13489a1d03eSRichard struct Empty {
EmptyEmpty13589a1d03eSRichard Empty(const Empty &Other) {}
13689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
13789a1d03eSRichard // CHECK-FIXES: Empty(const Empty &Other) = default;
13889a1d03eSRichard Empty &operator=(const Empty &);
13989a1d03eSRichard };
operator =(const Empty & Other)14089a1d03eSRichard Empty &Empty::operator=(const Empty &Other) { return *this; }
14189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use '= default'
14289a1d03eSRichard // CHECK-FIXES: Empty &Empty::operator=(const Empty &Other) = default;
14389a1d03eSRichard
14489a1d03eSRichard // Bit fields.
14589a1d03eSRichard struct BF {
14689a1d03eSRichard BF() = default;
BFBF14789a1d03eSRichard BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
14889a1d03eSRichard Field4(Other.Field4) {};
14989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
15089a1d03eSRichard // CHECK-FIXES: BF(const BF &Other) {{$}}
15189a1d03eSRichard // CHECK-FIXES: = default;
15289a1d03eSRichard BF &operator=(const BF &);
15389a1d03eSRichard
15489a1d03eSRichard unsigned Field1 : 3;
15589a1d03eSRichard int : 7;
15689a1d03eSRichard char Field2 : 6;
15789a1d03eSRichard int : 0;
15889a1d03eSRichard int Field3 : 24;
15989a1d03eSRichard unsigned char Field4;
16089a1d03eSRichard };
operator =(const BF & Other)16189a1d03eSRichard BF &BF::operator=(const BF &Other) {
16289a1d03eSRichard Field1 = Other.Field1;
16389a1d03eSRichard Field2 = Other.Field2;
16489a1d03eSRichard Field3 = Other.Field3;
16589a1d03eSRichard Field4 = Other.Field4;
16689a1d03eSRichard return *this;
16789a1d03eSRichard }
16889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-7]]:9: warning: use '= default'
16989a1d03eSRichard // CHECK-FIXES: BF &BF::operator=(const BF &Other) = default;
17089a1d03eSRichard
17189a1d03eSRichard // Base classes.
17289a1d03eSRichard struct BC : IL, OL, BF {
BCBC17389a1d03eSRichard BC(const BC &Other) : IL(Other), OL(Other), BF(Other) {}
17489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
17589a1d03eSRichard // CHECK-FIXES: BC(const BC &Other) = default;
17689a1d03eSRichard BC &operator=(const BC &Other);
17789a1d03eSRichard };
operator =(const BC & Other)17889a1d03eSRichard BC &BC::operator=(const BC &Other) {
17989a1d03eSRichard IL::operator=(Other);
18089a1d03eSRichard OL::operator=(Other);
18189a1d03eSRichard BF::operator=(Other);
18289a1d03eSRichard return *this;
18389a1d03eSRichard }
18489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-6]]:9: warning: use '= default'
18589a1d03eSRichard // CHECK-FIXES: BC &BC::operator=(const BC &Other) = default;
18689a1d03eSRichard
18789a1d03eSRichard // Base classes with member.
18889a1d03eSRichard struct BCWM : IL, OL {
BCWMBCWM18989a1d03eSRichard BCWM(const BCWM &Other) : IL(Other), OL(Other), Bf(Other.Bf) {}
19089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
19189a1d03eSRichard // CHECK-FIXES: BCWM(const BCWM &Other) = default;
19289a1d03eSRichard BCWM &operator=(const BCWM &);
19389a1d03eSRichard BF Bf;
19489a1d03eSRichard };
operator =(const BCWM & Other)19589a1d03eSRichard BCWM &BCWM::operator=(const BCWM &Other) {
19689a1d03eSRichard IL::operator=(Other);
19789a1d03eSRichard OL::operator=(Other);
19889a1d03eSRichard Bf = Other.Bf;
19989a1d03eSRichard return *this;
20089a1d03eSRichard }
20189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-6]]:13: warning: use '= default'
20289a1d03eSRichard // CHECK-FIXES: BCWM &BCWM::operator=(const BCWM &Other) = default;
20389a1d03eSRichard
20489a1d03eSRichard // Missing base class.
20589a1d03eSRichard struct MBC : IL, OL, BF {
MBCMBC20689a1d03eSRichard MBC(const MBC &Other) : IL(Other), OL(Other) {}
20789a1d03eSRichard MBC &operator=(const MBC &);
20889a1d03eSRichard };
operator =(const MBC & Other)20989a1d03eSRichard MBC &MBC::operator=(const MBC &Other) {
21089a1d03eSRichard IL::operator=(Other);
21189a1d03eSRichard OL::operator=(Other);
21289a1d03eSRichard return *this;
21389a1d03eSRichard }
21489a1d03eSRichard
21589a1d03eSRichard // Base classes, incorrect parameter.
21689a1d03eSRichard struct BCIP : BCWM, BF {
BCIPBCIP21789a1d03eSRichard BCIP(const BCIP &Other) : BCWM(Other), BF(Other.Bf) {}
21889a1d03eSRichard BCIP &operator=(const BCIP &);
21989a1d03eSRichard };
operator =(const BCIP & Other)22089a1d03eSRichard BCIP &BCIP::operator=(const BCIP &Other) {
22189a1d03eSRichard BCWM::operator=(Other);
22289a1d03eSRichard BF::operator=(Other.Bf);
22389a1d03eSRichard return *this;
22489a1d03eSRichard }
22589a1d03eSRichard
22689a1d03eSRichard // Virtual base classes.
22789a1d03eSRichard struct VA : virtual OL {};
22889a1d03eSRichard struct VB : virtual OL {};
22989a1d03eSRichard struct VBC : VA, VB, virtual OL {
23089a1d03eSRichard // OL is the first thing that is going to be initialized, despite the fact
23189a1d03eSRichard // that it is the last in the list of bases, because it is virtual and there
23289a1d03eSRichard // is a virtual OL at the beginning of VA (which is the same).
VBCVBC23389a1d03eSRichard VBC(const VBC &Other) : OL(Other), VA(Other), VB(Other) {}
23489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
23589a1d03eSRichard // CHECK-FIXES: VBC(const VBC &Other) = default;
23689a1d03eSRichard VBC &operator=(const VBC &Other);
23789a1d03eSRichard };
operator =(const VBC & Other)23889a1d03eSRichard VBC &VBC::operator=(const VBC &Other) {
23989a1d03eSRichard OL::operator=(Other);
24089a1d03eSRichard VA::operator=(Other);
24189a1d03eSRichard VB::operator=(Other);
24289a1d03eSRichard return *this;
24389a1d03eSRichard }
24489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-6]]:11: warning: use '= default'
24589a1d03eSRichard // CHECK-FIXES: VBC &VBC::operator=(const VBC &Other) = default;
24689a1d03eSRichard
24789a1d03eSRichard // Indirect base.
24889a1d03eSRichard struct IB : VBC {
IBIB24989a1d03eSRichard IB(const IB &Other) : OL(Other), VBC(Other) {}
25089a1d03eSRichard IB &operator=(const IB &);
25189a1d03eSRichard };
operator =(const IB & Other)25289a1d03eSRichard IB &IB::operator=(const IB &Other) {
25389a1d03eSRichard OL::operator=(Other);
25489a1d03eSRichard VBC::operator=(Other);
25589a1d03eSRichard return *this;
25689a1d03eSRichard }
25789a1d03eSRichard
25889a1d03eSRichard // Class template.
25989a1d03eSRichard template <class T>
26089a1d03eSRichard struct Template {
26189a1d03eSRichard Template() = default;
TemplateTemplate26289a1d03eSRichard Template(const Template &Other) : Field(Other.Field) {}
263*8009bbecSKrystian Stasiowski // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
264*8009bbecSKrystian Stasiowski // CHECK-FIXES: Template(const Template &Other) = default;
26589a1d03eSRichard Template &operator=(const Template &Other);
26689a1d03eSRichard void foo(const T &t);
26789a1d03eSRichard int Field;
26889a1d03eSRichard };
26989a1d03eSRichard template <class T>
operator =(const Template<T> & Other)27089a1d03eSRichard Template<T> &Template<T>::operator=(const Template<T> &Other) {
27189a1d03eSRichard Field = Other.Field;
27289a1d03eSRichard return *this;
27389a1d03eSRichard }
274*8009bbecSKrystian Stasiowski // CHECK-MESSAGES: :[[@LINE-4]]:27: warning: use '= default'
275*8009bbecSKrystian Stasiowski // CHECK-FIXES: Template<T> &Template<T>::operator=(const Template<T> &Other) = default;
276*8009bbecSKrystian Stasiowski
27789a1d03eSRichard Template<int> T1;
27889a1d03eSRichard
279*8009bbecSKrystian Stasiowski
28089a1d03eSRichard // Dependent types.
28189a1d03eSRichard template <class T>
28289a1d03eSRichard struct DT1 {
28389a1d03eSRichard DT1() = default;
DT1DT128489a1d03eSRichard DT1(const DT1 &Other) : Field(Other.Field) {}
28589a1d03eSRichard DT1 &operator=(const DT1 &);
28689a1d03eSRichard T Field;
28789a1d03eSRichard };
28889a1d03eSRichard template <class T>
operator =(const DT1<T> & Other)28989a1d03eSRichard DT1<T> &DT1<T>::operator=(const DT1<T> &Other) {
29089a1d03eSRichard Field = Other.Field;
29189a1d03eSRichard return *this;
29289a1d03eSRichard }
293*8009bbecSKrystian Stasiowski // CHECK-MESSAGES: :[[@LINE-4]]:17: warning: use '= default'
294*8009bbecSKrystian Stasiowski // CHECK-FIXES: DT1<T> &DT1<T>::operator=(const DT1<T> &Other) = default;
295*8009bbecSKrystian Stasiowski
29689a1d03eSRichard DT1<int> Dt1;
29789a1d03eSRichard
29889a1d03eSRichard template <class T>
29989a1d03eSRichard struct DT2 {
30089a1d03eSRichard DT2() = default;
DT2DT230189a1d03eSRichard DT2(const DT2 &Other) : Field(Other.Field), Dependent(Other.Dependent) {}
30289a1d03eSRichard DT2 &operator=(const DT2 &);
30389a1d03eSRichard T Field;
30489a1d03eSRichard typename T::TT Dependent;
30589a1d03eSRichard };
30689a1d03eSRichard template <class T>
operator =(const DT2<T> & Other)30789a1d03eSRichard DT2<T> &DT2<T>::operator=(const DT2<T> &Other) {
30889a1d03eSRichard Field = Other.Field;
30989a1d03eSRichard Dependent = Other.Dependent;
31089a1d03eSRichard return *this;
31189a1d03eSRichard }
31289a1d03eSRichard struct T {
31389a1d03eSRichard typedef int TT;
31489a1d03eSRichard };
315*8009bbecSKrystian Stasiowski // CHECK-MESSAGES: :[[@LINE-8]]:17: warning: use '= default'
316*8009bbecSKrystian Stasiowski // CHECK-FIXES: DT2<T> &DT2<T>::operator=(const DT2<T> &Other) = default;
317*8009bbecSKrystian Stasiowski
31889a1d03eSRichard DT2<T> Dt2;
31989a1d03eSRichard
32089a1d03eSRichard // Default arguments.
32189a1d03eSRichard struct DA {
32289a1d03eSRichard DA(int Int);
DADA32389a1d03eSRichard DA(const DA &Other = DA(0)) : Field1(Other.Field1), Field2(Other.Field2) {}
32489a1d03eSRichard DA &operator=(const DA &);
32589a1d03eSRichard int Field1;
32689a1d03eSRichard char Field2;
32789a1d03eSRichard };
32889a1d03eSRichard // Overloaded operator= cannot have a default argument.
operator =(const DA & Other)32989a1d03eSRichard DA &DA::operator=(const DA &Other) {
33089a1d03eSRichard Field1 = Other.Field1;
33189a1d03eSRichard Field2 = Other.Field2;
33289a1d03eSRichard return *this;
33389a1d03eSRichard }
33489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: use '= default'
33589a1d03eSRichard // CHECK-FIXES: DA &DA::operator=(const DA &Other) = default;
33689a1d03eSRichard
33789a1d03eSRichard struct DA2 {
33889a1d03eSRichard // Can be used as copy-constructor but cannot be explicitly defaulted.
DA2DA233989a1d03eSRichard DA2(const DA &Other, int Def = 0) {}
34089a1d03eSRichard };
34189a1d03eSRichard
34289a1d03eSRichard // Default initialization.
34389a1d03eSRichard struct DI {
DIDI34489a1d03eSRichard DI(const DI &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
34589a1d03eSRichard int Field1;
34689a1d03eSRichard int Field2 = 0;
34789a1d03eSRichard int Fiedl3;
34889a1d03eSRichard };
34989a1d03eSRichard
35089a1d03eSRichard // Statement inside body.
35189a1d03eSRichard void foo();
35289a1d03eSRichard struct SIB {
SIBSIB35389a1d03eSRichard SIB(const SIB &Other) : Field(Other.Field) { foo(); }
35489a1d03eSRichard SIB &operator=(const SIB &);
35589a1d03eSRichard int Field;
35689a1d03eSRichard };
operator =(const SIB & Other)35789a1d03eSRichard SIB &SIB::operator=(const SIB &Other) {
35889a1d03eSRichard Field = Other.Field;
35989a1d03eSRichard foo();
36089a1d03eSRichard return *this;
36189a1d03eSRichard }
36289a1d03eSRichard
36389a1d03eSRichard // Comment inside body.
36489a1d03eSRichard struct CIB {
CIBCIB36589a1d03eSRichard CIB(const CIB &Other) : Field(Other.Field) { /* Don't erase this */
36689a1d03eSRichard }
36789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
36889a1d03eSRichard CIB &operator=(const CIB &);
36989a1d03eSRichard int Field;
37089a1d03eSRichard };
operator =(const CIB & Other)37189a1d03eSRichard CIB &CIB::operator=(const CIB &Other) {
37289a1d03eSRichard Field = Other.Field;
37389a1d03eSRichard // FIXME: don't erase this comment.
37489a1d03eSRichard return *this;
37589a1d03eSRichard }
37689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:11: warning: use '= default'
37789a1d03eSRichard // CHECK-FIXES: CIB &CIB::operator=(const CIB &Other) = default;
37889a1d03eSRichard
37989a1d03eSRichard // Take non-const reference as argument.
38089a1d03eSRichard struct NCRef {
NCRefNCRef38189a1d03eSRichard NCRef(NCRef &Other) : Field1(Other.Field1), Field2(Other.Field2) {}
38289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
38389a1d03eSRichard // CHECK-FIXES: NCRef(NCRef &Other) = default;
38489a1d03eSRichard NCRef &operator=(NCRef &);
38589a1d03eSRichard int Field1, Field2;
38689a1d03eSRichard };
operator =(NCRef & Other)38789a1d03eSRichard NCRef &NCRef::operator=(NCRef &Other) {
38889a1d03eSRichard Field1 = Other.Field1;
38989a1d03eSRichard Field2 = Other.Field2;
39089a1d03eSRichard return *this;
39189a1d03eSRichard }
39289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-5]]:15: warning: use '= default'
39389a1d03eSRichard // CHECK-FIXES: NCRef &NCRef::operator=(NCRef &Other) = default;
39489a1d03eSRichard
39589a1d03eSRichard // Already defaulted.
39689a1d03eSRichard struct IAD {
39789a1d03eSRichard IAD(const IAD &Other) = default;
39889a1d03eSRichard IAD &operator=(const IAD &Other) = default;
39989a1d03eSRichard };
40089a1d03eSRichard
40189a1d03eSRichard struct OAD {
40289a1d03eSRichard OAD(const OAD &Other);
40389a1d03eSRichard OAD &operator=(const OAD &);
40489a1d03eSRichard };
40589a1d03eSRichard OAD::OAD(const OAD &Other) = default;
40689a1d03eSRichard OAD &OAD::operator=(const OAD &Other) = default;
40789a1d03eSRichard
40889a1d03eSRichard // Deleted.
40989a1d03eSRichard struct ID {
41089a1d03eSRichard ID(const ID &Other) = delete;
41189a1d03eSRichard ID &operator=(const ID &Other) = delete;
41289a1d03eSRichard };
41389a1d03eSRichard
41489a1d03eSRichard // Non-reference parameter.
41589a1d03eSRichard struct NRef {
41689a1d03eSRichard NRef &operator=(NRef Other);
41789a1d03eSRichard int Field1;
41889a1d03eSRichard };
operator =(NRef Other)41989a1d03eSRichard NRef &NRef::operator=(NRef Other) {
42089a1d03eSRichard Field1 = Other.Field1;
42189a1d03eSRichard return *this;
42289a1d03eSRichard }
42389a1d03eSRichard
42489a1d03eSRichard // RValue reference parameter.
42589a1d03eSRichard struct RVR {
RVRRVR42689a1d03eSRichard RVR(RVR &&Other) {}
42789a1d03eSRichard RVR &operator=(RVR &&);
42889a1d03eSRichard };
operator =(RVR && Other)42989a1d03eSRichard RVR &RVR::operator=(RVR &&Other) { return *this; }
43089a1d03eSRichard
43189a1d03eSRichard // Similar function.
43289a1d03eSRichard struct SF {
43389a1d03eSRichard SF &foo(const SF &);
43489a1d03eSRichard int Field1;
43589a1d03eSRichard };
foo(const SF & Other)43689a1d03eSRichard SF &SF::foo(const SF &Other) {
43789a1d03eSRichard Field1 = Other.Field1;
43889a1d03eSRichard return *this;
43989a1d03eSRichard }
44089a1d03eSRichard
44189a1d03eSRichard // No return.
44289a1d03eSRichard struct NR {
44389a1d03eSRichard NR &operator=(const NR &);
44489a1d03eSRichard };
operator =(const NR & Other)44589a1d03eSRichard NR &NR::operator=(const NR &Other) {}
44689a1d03eSRichard
44789a1d03eSRichard // Return misplaced.
44889a1d03eSRichard struct RM {
44989a1d03eSRichard RM &operator=(const RM &);
45089a1d03eSRichard int Field;
45189a1d03eSRichard };
operator =(const RM & Other)45289a1d03eSRichard RM &RM::operator=(const RM &Other) {
45389a1d03eSRichard return *this;
45489a1d03eSRichard Field = Other.Field;
45589a1d03eSRichard }
45689a1d03eSRichard
45789a1d03eSRichard // Wrong return value.
45889a1d03eSRichard struct WRV {
45989a1d03eSRichard WRV &operator=(WRV &);
46089a1d03eSRichard };
operator =(WRV & Other)46189a1d03eSRichard WRV &WRV::operator=(WRV &Other) {
46289a1d03eSRichard return Other;
46389a1d03eSRichard }
46489a1d03eSRichard
46589a1d03eSRichard // Wrong return type.
46689a1d03eSRichard struct WRT : IL {
46789a1d03eSRichard IL &operator=(const WRT &);
46889a1d03eSRichard };
operator =(const WRT & Other)46989a1d03eSRichard IL &WRT::operator=(const WRT &Other) {
47089a1d03eSRichard return *this;
47189a1d03eSRichard }
47289a1d03eSRichard
473a7395b86SAlexander Shaposhnikov // Wrong return type.
474a7395b86SAlexander Shaposhnikov struct WRTConstRef {
operator =WRTConstRef475a7395b86SAlexander Shaposhnikov const WRTConstRef &operator = (const WRTConstRef &) {
476a7395b86SAlexander Shaposhnikov return *this;
477a7395b86SAlexander Shaposhnikov }
478a7395b86SAlexander Shaposhnikov };
479a7395b86SAlexander Shaposhnikov
48089a1d03eSRichard // Try-catch.
48189a1d03eSRichard struct ITC {
ITCITC48289a1d03eSRichard ITC(const ITC &Other)
48389a1d03eSRichard try : Field(Other.Field) {
48489a1d03eSRichard } catch (...) {
48589a1d03eSRichard }
operator =ITC48689a1d03eSRichard ITC &operator=(const ITC &Other) try {
48789a1d03eSRichard Field = Other.Field;
48889a1d03eSRichard } catch (...) {
48989a1d03eSRichard }
49089a1d03eSRichard int Field;
49189a1d03eSRichard };
49289a1d03eSRichard
49389a1d03eSRichard struct OTC {
49489a1d03eSRichard OTC(const OTC &);
49589a1d03eSRichard OTC &operator=(const OTC &);
49689a1d03eSRichard int Field;
49789a1d03eSRichard };
OTC(const OTC & Other)49889a1d03eSRichard OTC::OTC(const OTC &Other) try : Field(Other.Field) {
49989a1d03eSRichard } catch (...) {
50089a1d03eSRichard }
operator =(const OTC & Other)50189a1d03eSRichard OTC &OTC::operator=(const OTC &Other) try {
50289a1d03eSRichard Field = Other.Field;
50389a1d03eSRichard } catch (...) {
50489a1d03eSRichard }
50589a1d03eSRichard
50689a1d03eSRichard // FIXME: the check is not able to detect exception specification.
50789a1d03eSRichard // noexcept(true).
50889a1d03eSRichard struct NET {
50989a1d03eSRichard // This is the default.
51089a1d03eSRichard //NET(const NET &Other) noexcept {}
51189a1d03eSRichard NET &operator=(const NET &Other) noexcept;
51289a1d03eSRichard };
51389a1d03eSRichard //NET &NET::operator=(const NET &Other) noexcept { return *this; }
51489a1d03eSRichard
51589a1d03eSRichard // noexcept(false).
51689a1d03eSRichard struct NEF {
51789a1d03eSRichard // This is the default.
51889a1d03eSRichard //NEF(const NEF &Other) noexcept(false) {}
51989a1d03eSRichard NEF &operator=(const NEF &Other) noexcept(false);
52089a1d03eSRichard };
52189a1d03eSRichard //NEF &NEF::operator=(const NEF &Other) noexcept(false) { return *this; }
52289a1d03eSRichard
52389a1d03eSRichard #define STRUCT_WITH_COPY_CONSTRUCT(_base, _type) \
52489a1d03eSRichard struct _type { \
52589a1d03eSRichard _type(const _type &v) : value(v.value) {} \
52689a1d03eSRichard _base value; \
52789a1d03eSRichard };
52889a1d03eSRichard
52989a1d03eSRichard STRUCT_WITH_COPY_CONSTRUCT(unsigned char, Hex8CopyConstruct)
53089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy constructor
53189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-6]]:44: note:
53289a1d03eSRichard
53389a1d03eSRichard #define STRUCT_WITH_COPY_ASSIGN(_base, _type) \
53489a1d03eSRichard struct _type { \
53589a1d03eSRichard _type &operator=(const _type &rhs) { \
53689a1d03eSRichard value = rhs.value; \
53789a1d03eSRichard return *this; \
53889a1d03eSRichard } \
53989a1d03eSRichard _base value; \
54089a1d03eSRichard };
54189a1d03eSRichard
54289a1d03eSRichard STRUCT_WITH_COPY_ASSIGN(unsigned char, Hex8CopyAssign)
54389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use '= default' to define a trivial copy-assignment operator
54489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-9]]:40: note:
54589a1d03eSRichard
54689a1d03eSRichard // Use of braces
54789a1d03eSRichard struct UOB{
UOBUOB54889a1d03eSRichard UOB(const UOB &Other):j{Other.j}{}
54989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' to define a trivial copy constructor [modernize-use-equals-default]
55089a1d03eSRichard // CHECK-FIXES: UOB(const UOB &Other)= default;
55189a1d03eSRichard int j;
55289a1d03eSRichard };
553