Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit a2e76f5

Browse files
committed
[class.copy]p23: Fix an assertion caused by incorrect argument numbering in a
diagnostic, add a test for this paragraph, and tighten up the diagnostic wording a little. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155784 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent e593921 commit a2e76f5

File tree

6 files changed

+149
-15
lines changed

6 files changed

+149
-15
lines changed

include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,8 +2897,8 @@ def note_deleted_dtor_no_operator_delete : Note<
28972897
def note_deleted_special_member_class_subobject : Note<
28982898
"%select{default constructor|copy constructor|move constructor|"
28992899
"copy assignment operator|move assignment operator|destructor}0 of "
2900-
"%select{||||union }4%1 is implicitly deleted because "
2901-
"%select{base class %3|field %3}2 has "
2900+
"%1 is implicitly deleted because "
2901+
"%select{base class %3|%select{||||variant }4field %3}2 has "
29022902
"%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 "
29032903
"%select{%select{default constructor|copy constructor|move constructor|copy "
29042904
"assignment operator|move assignment operator|destructor}0|destructor}5"
@@ -2917,8 +2917,8 @@ def note_deleted_copy_user_declared_move : Note<
29172917
"copy %select{constructor|assignment operator}0 is implicitly deleted because"
29182918
" %1 has a user-declared move %select{constructor|assignment operator}2">;
29192919
def note_deleted_assign_field : Note<
2920-
"%select{copy|move}0 assignment operator of %0 is implicitly deleted "
2921-
"because field %1 is of %select{reference|const-qualified}3 type %2">;
2920+
"%select{copy|move}0 assignment operator of %1 is implicitly deleted "
2921+
"because field %2 is of %select{reference|const-qualified}4 type %3">;
29222922

29232923
// This should eventually be an error.
29242924
def warn_undefined_internal : Warning<

lib/Sema/SemaDeclCXX.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4549,7 +4549,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
45494549
(!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor())) {
45504550
if (Diagnose)
45514551
S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field)
4552-
<< MD->getParent() << FD << FieldType << /*Const*/1;
4552+
<< MD->getParent() << FD << FD->getType() << /*Const*/1;
45534553
return true;
45544554
}
45554555

@@ -4577,7 +4577,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
45774577
// -- a non-static data member of const non-class type (or array thereof)
45784578
if (Diagnose)
45794579
S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
4580-
<< IsMove << MD->getParent() << FD << FieldType << /*Const*/1;
4580+
<< IsMove << MD->getParent() << FD << FD->getType() << /*Const*/1;
45814581
return true;
45824582
}
45834583
}

test/CXX/special/class.copy/p11.0x.copy.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ struct NonTrivial {
88

99
// -- a variant member with a non-trivial corresponding constructor
1010
union DeletedNTVariant {
11-
NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
11+
NonTrivial NT; // expected-note{{copy constructor of 'DeletedNTVariant' is implicitly deleted because variant field 'NT' has a non-trivial copy constructor}}
1212
DeletedNTVariant();
1313
};
1414
DeletedNTVariant DVa;
1515
DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
1616

1717
struct DeletedNTVariant2 {
1818
union {
19-
NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant2' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
19+
NonTrivial NT; // expected-note{{copy constructor of 'DeletedNTVariant2' is implicitly deleted because variant field 'NT' has a non-trivial copy constructor}}
2020
};
2121
DeletedNTVariant2();
2222
};
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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}}

test/CXX/special/class.ctor/p5-0x.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ int n;
2121

2222
// - X is a union-like class that has a variant member with a non-trivial
2323
// default constructor,
24-
union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of union 'Deleted1a' is implicitly deleted because field 'u' has a non-trivial default constructor}}
24+
union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of 'Deleted1a' is implicitly deleted because variant field 'u' has a non-trivial default constructor}}
2525
Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
2626
union NotDeleted1a { DefaultedDefCtor1 nu; };
2727
NotDeleted1a nd1a;
@@ -53,7 +53,7 @@ class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-
5353
expected-warning {{does not declare any constructor}} \
5454
expected-note {{will never be initialized}}
5555
Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
56-
class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1' would not be initialized}}
56+
class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1 [42]' would not be initialized}}
5757
Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
5858
class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}}
5959
Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
@@ -77,7 +77,7 @@ NotDeleted3g nd3g;
7777
union Deleted4a {
7878
const int a;
7979
const int b;
80-
const UserProvidedDefCtor c; // expected-note {{because field 'c' has a non-trivial default constructor}}
80+
const UserProvidedDefCtor c; // expected-note {{because variant field 'c' has a non-trivial default constructor}}
8181
};
8282
Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
8383
union NotDeleted4a { const int a; int b; };

test/CXX/special/class.dtor/p5-0x.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,25 @@ class InaccessibleDtor {
1616
// destructor.
1717
union A1 {
1818
A1();
19-
NonTrivDtor n; // expected-note {{destructor of union 'A1' is implicitly deleted because field 'n' has a non-trivial destructor}}
19+
NonTrivDtor n; // expected-note {{destructor of 'A1' is implicitly deleted because variant field 'n' has a non-trivial destructor}}
2020
};
2121
A1 a1; // expected-error {{deleted function}}
2222
struct A2 {
2323
A2();
2424
union {
25-
NonTrivDtor n; // expected-note {{because field 'n' has a non-trivial destructor}}
25+
NonTrivDtor n; // expected-note {{because variant field 'n' has a non-trivial destructor}}
2626
};
2727
};
2828
A2 a2; // expected-error {{deleted function}}
2929
union A3 {
3030
A3();
31-
NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
31+
NonTrivDtor n[3]; // expected-note {{because variant field 'n' has a non-trivial destructor}}
3232
};
3333
A3 a3; // expected-error {{deleted function}}
3434
struct A4 {
3535
A4();
3636
union {
37-
NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
37+
NonTrivDtor n[3]; // expected-note {{because variant field 'n' has a non-trivial destructor}}
3838
};
3939
};
4040
A4 a4; // expected-error {{deleted function}}

0 commit comments

Comments
 (0)