1 // RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s
2 // RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s
3 // RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++20 %s
4 
5 #if __cplusplus >= 202002L
6 
7 class EqDefaultCompare {
8   int used;
9 
10 public:
EqDefaultCompare(int x)11   EqDefaultCompare(int x) : used(x) {}
12   bool operator==(const EqDefaultCompare &) const = default;
13 };
14 
15 class SpaceShipDefaultCompare {
16   int used;
17 
18 public:
SpaceShipDefaultCompare(int x)19   SpaceShipDefaultCompare(int x) : used(x) {}
20   int operator<=>(const SpaceShipDefaultCompare &) const = default;
21 };
22 
23 #endif
24 
25 class NotFullyDefined {
26  public:
27   NotFullyDefined();
28  private:
29   int y;
30 };
31 
32 class HasUndefinedNestedClass {
33   class Undefined;
34   int unused_;
35 };
36 
37 class HasUndefinedPureVirtualDestructor {
38   virtual ~HasUndefinedPureVirtualDestructor() = 0;
39   int unused_;
40 };
41 
42 class HasDefinedNestedClasses {
43   class DefinedHere {};
44   class DefinedOutside;
45   int unused_; // expected-warning{{private field 'unused_' is not used}}
46 };
47 class HasDefinedNestedClasses::DefinedOutside {};
48 
49 class HasUndefinedFriendFunction {
50   friend void undefinedFriendFunction();
51   int unused_;
52 };
53 
54 class HasUndefinedFriendClass {
55   friend class NotFullyDefined;
56   friend class NotDefined;
57   int unused_;
58 };
59 
60 class HasFriend {
61   friend class FriendClass;
62   friend void friendFunction(HasFriend f);
63   int unused_; // expected-warning{{private field 'unused_' is not used}}
64   int used_by_friend_class_;
65   int used_by_friend_function_;
66 };
67 
68 class ClassWithTemplateFriend {
69   template <typename T> friend class TemplateFriend;
70   int used_by_friend_;
71   int unused_;
72 };
73 
74 template <typename T> class TemplateFriend {
75 public:
TemplateFriend(ClassWithTemplateFriend my_friend)76   TemplateFriend(ClassWithTemplateFriend my_friend) {
77     int var = my_friend.used_by_friend_;
78   }
79 };
80 
81 class FriendClass {
82   HasFriend my_friend_;
use()83   void use() {
84     my_friend_.used_by_friend_class_ = 42;
85   }
86 };
87 
friendFunction(HasFriend my_friend)88 void friendFunction(HasFriend my_friend) {
89   my_friend.used_by_friend_function_ = 42;
90 }
91 
92 class NonTrivialConstructor {
93  public:
NonTrivialConstructor()94   NonTrivialConstructor() {}
95 };
96 
97 class NonTrivialDestructor {
98  public:
~NonTrivialDestructor()99   ~NonTrivialDestructor() {}
100 };
101 
102 class Trivial {
103  public:
104   Trivial() = default;
Trivial(int a)105   Trivial(int a) {}
106 };
107 
side_effect()108 int side_effect() {
109   return 42;
110 }
111 
112 class A {
113  public:
A()114   A() : primitive_type_(42), default_initializer_(), other_initializer_(42),
115         trivial_(), user_constructor_(42),
116         initialized_with_side_effect_(side_effect()) {
117     used_ = 42;
118     attr_used_ = 42; // expected-warning{{'attr_used_' was marked unused but was used}}
119   }
120 
A(int x,A * a)121   A(int x, A* a) : pointer_(a) {}
122 
123  private:
124   int primitive_type_; // expected-warning{{private field 'primitive_type_' is not used}}
125   A* pointer_; // expected-warning{{private field 'pointer_' is not used}}
126   int no_initializer_; // expected-warning{{private field 'no_initializer_' is not used}}
127   int default_initializer_; // expected-warning{{private field 'default_initializer_' is not used}}
128   int other_initializer_; // expected-warning{{private field 'other_initializer_' is not used}}
129   int used_, unused_; // expected-warning{{private field 'unused_' is not used}}
130   int in_class_initializer_ = 42; // expected-warning{{private field 'in_class_initializer_' is not used}}
131   int in_class_initializer_with_side_effect_ = side_effect();
132   Trivial trivial_initializer_ = Trivial(); // expected-warning{{private field 'trivial_initializer_' is not used}}
133   Trivial non_trivial_initializer_ = Trivial(42);
134   int initialized_with_side_effect_;
135   static int static_fields_are_ignored_;
136 
137   Trivial trivial_; // expected-warning{{private field 'trivial_' is not used}}
138   Trivial user_constructor_;
139   NonTrivialConstructor non_trivial_constructor_;
140   NonTrivialDestructor non_trivial_destructor_;
141 
142   int attr_ __attribute__((unused));
143   int attr_used_ __attribute__((unused));
144 };
145 
146 class EverythingUsed {
147  public:
EverythingUsed()148   EverythingUsed() : as_array_index_(0), var_(by_initializer_) {
149     var_ = sizeof(sizeof_);
150     int *use = &by_reference_;
151     int test[2];
152     test[as_array_index_] = 42;
153     int EverythingUsed::*ptr = &EverythingUsed::by_pointer_to_member_;
154   }
155 
156   template<class T>
useStuff(T t)157   void useStuff(T t) {
158     by_template_function_ = 42;
159   }
160 
161  private:
162   int var_;
163   int sizeof_;
164   int by_reference_;
165   int by_template_function_;
166   int as_array_index_;
167   int by_initializer_;
168   int by_pointer_to_member_;
169 };
170 
171 class HasFeatureTest {
172 #if __has_feature(attribute_unused_on_fields)
173   int unused_; // expected-warning{{private field 'unused_' is not used}}
174   int unused2_ __attribute__((unused)); // no-warning
175 #endif
176 };
177 
178 namespace templates {
179 class B {
180   template <typename T> void f(T t);
181   int a;
182 };
183 }  // namespace templates
184 
185 namespace mutual_friends {
186 // Undefined methods make mutual friends undefined.
187 class A {
188   int a;
189   friend class B;
190   void doSomethingToAOrB();
191 };
192 class B {
193   int b;
194   friend class A;
195 };
196 
197 // Undefined friends do not make a mutual friend undefined.
198 class C {
199   int c;
doSomethingElse()200   void doSomethingElse() {}
201   friend class E;
202   friend class D;
203 };
204 class D {
205   int d; // expected-warning{{private field 'd' is not used}}
206   friend class C;
207 };
208 
209 // Undefined nested classes make mutual friends undefined.
210 class F {
211   int f;
212   class G;
213   friend class H;
214 };
215 class H {
216   int h;
217   friend class F;
218 };
219 }  // namespace mutual_friends
220 
221 namespace anonymous_structs_unions {
222 class A {
223  private:
224   // FIXME: Look at the DeclContext for anonymous structs/unions.
225   union {
226     int *Aligner;
227     unsigned char Data[8];
228   };
229 };
230 union S {
231  private:
232   int *Aligner;
233   unsigned char Data[8];
234 };
235 }  // namespace anonymous_structs_unions
236 
237 namespace pr13413 {
238 class A {
A()239   A() : p_(__null), b_(false), a_(this), p2_(nullptr) {}
240   void* p_;  // expected-warning{{private field 'p_' is not used}}
241   bool b_;  // expected-warning{{private field 'b_' is not used}}
242   A* a_;  // expected-warning{{private field 'a_' is not used}}
243   void* p2_;  // expected-warning{{private field 'p2_' is not used}}
244 };
245 }
246 
247 namespace pr13543 {
248   void f(int);
249   void f(char);
250   struct S {
Spr13543::S251     S() : p(&f) {}
252   private:
253     void (*p)(int); // expected-warning{{private field 'p' is not used}}
254   };
255 
256   struct A { int n; };
257   struct B {
Bpr13543::B258     B() : a(A()) {}
Bpr13543::B259     B(char) {}
Bpr13543::B260     B(int n) : a{n}, b{(f(n), 0)} {}
261   private:
262     A a = A(); // expected-warning{{private field 'a' is not used}}
263     A b;
264   };
265 
266   struct X { ~X(); };
267   class C {
268     X x[4]; // no-warning
269   };
270 }
271 
272 class implicit_special_member {
273 public:
make()274   static implicit_special_member make() { return implicit_special_member(); }
275 
276 private:
277   int n; // expected-warning{{private field 'n' is not used}}
278 };
279 
280 class defaulted_special_member {
281 public:
282   defaulted_special_member(const defaulted_special_member&) = default;
283 
284 private:
285   int n; // expected-warning{{private field 'n' is not used}}
286 };
287