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