1 // RUN: %check_clang_tidy %s readability-deleted-default %t -- -- -fno-ms-compatibility
2
3 class NoDefault {
4 public:
5 NoDefault() = delete;
6 NoDefault(NoDefault &&Other) = delete;
7 NoDefault(const NoDefault &Other) = delete;
8 };
9
10 class MissingEverything {
11 public:
12 MissingEverything() = default;
13 // CHECK-MESSAGES: warning: default constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is lacking a default constructor; definition can either be removed or explicitly deleted [readability-deleted-default]
14 MissingEverything(MissingEverything &&Other) = default;
15 // CHECK-MESSAGES: warning: move constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is neither copyable nor movable; definition can either be removed or explicitly deleted [readability-deleted-default]
16 MissingEverything(const MissingEverything &Other) = default;
17 // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted, probably because a non-static data member or a base class is not copyable; definition can either be removed or explicitly deleted [readability-deleted-default]
18 MissingEverything &operator=(MissingEverything &&Other) = default;
19 // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
20 MissingEverything &operator=(const MissingEverything &Other) = default;
21 // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted, probably because a base class or a non-static data member is not assignable, e.g. because the latter is marked 'const'; definition can either be removed or explicitly deleted [readability-deleted-default]
22
23 private:
24 NoDefault ND;
25 };
26
27 class NotAssignable {
28 public:
29 NotAssignable(NotAssignable &&Other) = default;
30 NotAssignable(const NotAssignable &Other) = default;
31 NotAssignable &operator=(NotAssignable &&Other) = default;
32 // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
33 NotAssignable &operator=(const NotAssignable &Other) = default;
34 // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
35
36 private:
37 const int I = 0;
38 };
39
40 class Movable {
41 public:
42 Movable() = default;
43 Movable(Movable &&Other) = default;
44 Movable(const Movable &Other) = delete;
45 Movable &operator=(Movable &&Other) = default;
46 Movable &operator=(const Movable &Other) = delete;
47 };
48
49 class NotCopyable {
50 public:
51 NotCopyable(NotCopyable &&Other) = default;
52 NotCopyable(const NotCopyable &Other) = default;
53 // CHECK-MESSAGES: warning: copy constructor is explicitly defaulted but implicitly deleted
54 NotCopyable &operator=(NotCopyable &&Other) = default;
55 NotCopyable &operator=(const NotCopyable &Other) = default;
56 // CHECK-MESSAGES: warning: copy assignment operator is explicitly defaulted but implicitly deleted
57 private:
58 Movable M;
59 };
60
61 template <typename T> class Templated {
62 public:
63 // No warning here, it is a templated class.
64 Templated() = default;
65 Templated(Templated &&Other) = default;
66 Templated(const Templated &Other) = default;
67 Templated &operator=(Templated &&Other) = default;
68 Templated &operator=(const Templated &Other) = default;
69
70 class InnerTemplated {
71 public:
72 // This class is not in itself templated, but we still don't have warning.
73 InnerTemplated() = default;
74 InnerTemplated(InnerTemplated &&Other) = default;
75 InnerTemplated(const InnerTemplated &Other) = default;
76 InnerTemplated &operator=(InnerTemplated &&Other) = default;
77 InnerTemplated &operator=(const InnerTemplated &Other) = default;
78
79 private:
80 T TVar;
81 };
82
83 class InnerNotTemplated {
84 public:
85 // This one could technically have warnings, but currently doesn't.
86 InnerNotTemplated() = default;
87 InnerNotTemplated(InnerNotTemplated &&Other) = default;
88 InnerNotTemplated(const InnerNotTemplated &Other) = default;
89 InnerNotTemplated &operator=(InnerNotTemplated &&Other) = default;
90 InnerNotTemplated &operator=(const InnerNotTemplated &Other) = default;
91
92 private:
93 int I;
94 };
95
96 private:
97 const T TVar{};
98 };
99
FunctionWithInnerClass()100 int FunctionWithInnerClass() {
101 class InnerNotAssignable {
102 public:
103 InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
104 // CHECK-MESSAGES: warning: move assignment operator is explicitly defaulted but implicitly deleted
105 private:
106 const int I = 0;
107 };
108 return 1;
109 };
110
111 template <typename T>
TemplateFunctionWithInnerClass()112 int TemplateFunctionWithInnerClass() {
113 class InnerNotAssignable {
114 public:
115 InnerNotAssignable &operator=(InnerNotAssignable &&Other) = default;
116 private:
117 const T TVar{};
118 };
119 return 1;
120 };
121
Foo()122 void Foo() {
123 Templated<const int> V1;
124 Templated<int>::InnerTemplated V2;
125 Templated<float>::InnerNotTemplated V3;
126 TemplateFunctionWithInnerClass<int>();
127 }
128