1 // RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s 2 // RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s 3 // RUN: %clang_cc1 -fsyntax-only -Wunused -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: 11 EqDefaultCompare(int x) : used(x) {} 12 bool operator==(const EqDefaultCompare &) const = default; 13 }; 14 15 class SpaceShipDefaultCompare { 16 int used; 17 18 public: 19 SpaceShipDefaultCompare(int x) : used(x) {} 20 int operator<=>(const SpaceShipDefaultCompare &) const = default; 21 }; 22 23 class EqDefaultCompareOutOfClass { 24 int used; // no warning, the compiler generated AST for the comparison operator 25 // references the fields of the class, and this should be considered 26 // a use. 27 // This test case is needed because clang does not emit the body 28 // of the defaulted operator when it is defined in-class until it 29 // finds a call to it. `-Wunused-private-field` is suppressed in 30 // a different way in that case. 31 bool operator==(const EqDefaultCompareOutOfClass &) const; 32 }; 33 34 bool EqDefaultCompareOutOfClass::operator==(const EqDefaultCompareOutOfClass &) const = default; 35 36 class FriendEqDefaultCompareOutOfClass { 37 int used; // no warning, same reasoning just tested via a friend declaration. 38 friend bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &); 39 }; 40 41 bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &) = default; 42 43 class HasUnusedField { 44 int unused_; // expected-warning{{private field 'unused_' is not used}} 45 }; 46 47 class FriendEqDefaultCompare { 48 int used; 49 friend auto operator==(FriendEqDefaultCompare, FriendEqDefaultCompare) -> bool = default; 50 }; 51 52 class UnrelatedFriendEqDefaultCompare { 53 friend auto operator==(UnrelatedFriendEqDefaultCompare, UnrelatedFriendEqDefaultCompare) -> bool = default; 54 int operator<=>(const UnrelatedFriendEqDefaultCompare &) const = default; 55 }; 56 57 #endif 58 59 class NotFullyDefined { 60 public: 61 NotFullyDefined(); 62 private: 63 int y; 64 }; 65 66 class HasUndefinedNestedClass { 67 class Undefined; 68 int unused_; 69 }; 70 71 class HasUndefinedPureVirtualDestructor { 72 virtual ~HasUndefinedPureVirtualDestructor() = 0; 73 int unused_; 74 }; 75 76 class HasDefinedNestedClasses { 77 class DefinedHere {}; 78 class DefinedOutside; 79 int unused_; // expected-warning{{private field 'unused_' is not used}} 80 }; 81 class HasDefinedNestedClasses::DefinedOutside {}; 82 83 class HasUndefinedFriendFunction { 84 friend void undefinedFriendFunction(); 85 int unused_; 86 }; 87 88 class HasUndefinedFriendClass { 89 friend class NotFullyDefined; 90 friend class NotDefined; 91 int unused_; 92 }; 93 94 class HasFriend { 95 friend class FriendClass; 96 friend void friendFunction(HasFriend f); 97 int unused_; // expected-warning{{private field 'unused_' is not used}} 98 int used_by_friend_class_; 99 int used_by_friend_function_; 100 }; 101 102 class ClassWithTemplateFriend { 103 template <typename T> friend class TemplateFriend; 104 int used_by_friend_; 105 int unused_; 106 }; 107 108 template <typename T> class TemplateFriend { 109 public: 110 TemplateFriend(ClassWithTemplateFriend my_friend) { 111 int var = my_friend.used_by_friend_; // expected-warning {{unused variable 'var'}} 112 } 113 }; 114 115 class FriendClass { 116 HasFriend my_friend_; 117 void use() { 118 my_friend_.used_by_friend_class_ = 42; 119 } 120 }; 121 122 void friendFunction(HasFriend my_friend) { 123 my_friend.used_by_friend_function_ = 42; 124 } 125 126 class NonTrivialConstructor { 127 public: 128 NonTrivialConstructor() {} 129 }; 130 131 class NonTrivialDestructor { 132 public: 133 ~NonTrivialDestructor() {} 134 }; 135 136 class Trivial { 137 public: 138 Trivial() = default; 139 Trivial(int a) {} 140 }; 141 142 int side_effect() { 143 return 42; 144 } 145 146 class A { 147 public: 148 A() : primitive_type_(42), default_initializer_(), other_initializer_(42), 149 trivial_(), user_constructor_(42), 150 initialized_with_side_effect_(side_effect()) { 151 used_ = 42; 152 attr_used_ = 42; // expected-warning{{'attr_used_' was marked unused but was used}} 153 } 154 155 A(int x, A* a) : pointer_(a) {} 156 157 private: 158 int primitive_type_; // expected-warning{{private field 'primitive_type_' is not used}} 159 A* pointer_; // expected-warning{{private field 'pointer_' is not used}} 160 int no_initializer_; // expected-warning{{private field 'no_initializer_' is not used}} 161 int default_initializer_; // expected-warning{{private field 'default_initializer_' is not used}} 162 int other_initializer_; // expected-warning{{private field 'other_initializer_' is not used}} 163 int used_, unused_; // expected-warning{{private field 'unused_' is not used}} 164 int in_class_initializer_ = 42; // expected-warning{{private field 'in_class_initializer_' is not used}} 165 int in_class_initializer_with_side_effect_ = side_effect(); 166 Trivial trivial_initializer_ = Trivial(); // expected-warning{{private field 'trivial_initializer_' is not used}} 167 Trivial non_trivial_initializer_ = Trivial(42); 168 int initialized_with_side_effect_; 169 static int static_fields_are_ignored_; 170 171 Trivial trivial_; // expected-warning{{private field 'trivial_' is not used}} 172 Trivial user_constructor_; 173 NonTrivialConstructor non_trivial_constructor_; 174 NonTrivialDestructor non_trivial_destructor_; 175 176 int attr_ __attribute__((unused)); 177 int attr_used_ __attribute__((unused)); 178 }; 179 180 class EverythingUsed { 181 public: 182 EverythingUsed() : as_array_index_(0), var_(by_initializer_) { 183 var_ = sizeof(sizeof_); 184 int *use = &by_reference_; // expected-warning {{unused variable 'use'}} 185 int test[2]; 186 test[as_array_index_] = 42; 187 int EverythingUsed::*ptr = &EverythingUsed::by_pointer_to_member_; // expected-warning {{unused variable 'ptr'}} 188 } 189 190 template<class T> 191 void useStuff(T t) { 192 by_template_function_ = 42; 193 } 194 195 private: 196 int var_; 197 int sizeof_; 198 int by_reference_; 199 int by_template_function_; 200 int as_array_index_; 201 int by_initializer_; 202 int by_pointer_to_member_; 203 }; 204 205 class HasFeatureTest { 206 #if __has_feature(attribute_unused_on_fields) 207 int unused_; // expected-warning{{private field 'unused_' is not used}} 208 int unused2_ __attribute__((unused)); // no-warning 209 #endif 210 }; 211 212 namespace templates { 213 class B { 214 template <typename T> void f(T t); 215 int a; 216 }; 217 } // namespace templates 218 219 namespace mutual_friends { 220 // Undefined methods make mutual friends undefined. 221 class A { 222 int a; 223 friend class B; 224 void doSomethingToAOrB(); 225 }; 226 class B { 227 int b; 228 friend class A; 229 }; 230 231 // Undefined friends do not make a mutual friend undefined. 232 class C { 233 int c; 234 void doSomethingElse() {} 235 friend class E; 236 friend class D; 237 }; 238 class D { 239 int d; // expected-warning{{private field 'd' is not used}} 240 friend class C; 241 }; 242 243 // Undefined nested classes make mutual friends undefined. 244 class F { 245 int f; 246 class G; 247 friend class H; 248 }; 249 class H { 250 int h; 251 friend class F; 252 }; 253 } // namespace mutual_friends 254 255 namespace anonymous_structs_unions { 256 class A { 257 private: 258 // FIXME: Look at the DeclContext for anonymous structs/unions. 259 union { 260 int *Aligner; 261 unsigned char Data[8]; 262 }; 263 }; 264 union S { 265 private: 266 int *Aligner; 267 unsigned char Data[8]; 268 }; 269 } // namespace anonymous_structs_unions 270 271 namespace pr13413 { 272 class A { 273 A() : p_(__null), b_(false), a_(this), p2_(nullptr) {} 274 void* p_; // expected-warning{{private field 'p_' is not used}} 275 bool b_; // expected-warning{{private field 'b_' is not used}} 276 A* a_; // expected-warning{{private field 'a_' is not used}} 277 void* p2_; // expected-warning{{private field 'p2_' is not used}} 278 }; 279 } 280 281 namespace pr13543 { 282 void f(int); 283 void f(char); 284 struct S { 285 S() : p(&f) {} 286 private: 287 void (*p)(int); // expected-warning{{private field 'p' is not used}} 288 }; 289 290 struct A { int n; }; 291 struct B { 292 B() : a(A()) {} 293 B(char) {} 294 B(int n) : a{n}, b{(f(n), 0)} {} 295 private: 296 A a = A(); // expected-warning{{private field 'a' is not used}} 297 A b; 298 }; 299 300 struct X { ~X(); }; 301 class C { 302 X x[4]; // no-warning 303 }; 304 } 305 306 class implicit_special_member { 307 public: 308 static implicit_special_member make() { return implicit_special_member(); } 309 310 private: 311 int n; // expected-warning{{private field 'n' is not used}} 312 }; 313 314 class defaulted_special_member { 315 public: 316 defaulted_special_member(const defaulted_special_member&) = default; 317 318 private: 319 int n; // expected-warning{{private field 'n' is not used}} 320 }; 321 322 namespace pr61334 { 323 class [[maybe_unused]] MaybeUnusedClass {}; 324 enum [[maybe_unused]] MaybeUnusedEnum {}; 325 typedef int MaybeUnusedTypedef [[maybe_unused]]; 326 class C { 327 MaybeUnusedClass c; // no-warning 328 MaybeUnusedEnum e; // no-warning 329 MaybeUnusedTypedef t; // no-warning 330 }; 331 } 332 333 namespace GH62472 { 334 class [[gnu::warn_unused]] S { 335 public: 336 S(); 337 }; 338 339 struct [[maybe_unused]] T {}; 340 341 void f() { 342 int i = 0; // expected-warning {{unused variable 'i'}} 343 S s; // expected-warning {{unused variable 's'}} 344 T t; // ok 345 } 346 347 class C { 348 private: 349 const int i = 0; // expected-warning {{private field 'i' is not used}} 350 int j = 0; // expected-warning {{private field 'j' is not used}} 351 const S s1; // expected-warning {{private field 's1' is not used}} 352 const T t1; // ok 353 S s2; // expected-warning {{private field 's2' is not used}} 354 T t2; // ok 355 }; 356 } 357