| 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: |
| 55 | TemplateFriend(ClassWithTemplateFriend my_friend) { |
| 56 | int var = my_friend.used_by_friend_; |
| 57 | } |
| 58 | }; |
| 59 | |
| 60 | class FriendClass { |
| 61 | HasFriend my_friend_; |
| 62 | void use() { |
| 63 | my_friend_.used_by_friend_class_ = 42; |
| 64 | } |
| 65 | }; |
| 66 | |
| 67 | void friendFunction(HasFriend my_friend) { |
| 68 | my_friend.used_by_friend_function_ = 42; |
| 69 | } |
| 70 | |
| 71 | class NonTrivialConstructor { |
| 72 | public: |
| 73 | NonTrivialConstructor() {} |
| 74 | }; |
| 75 | |
| 76 | class NonTrivialDestructor { |
| 77 | public: |
| 78 | ~NonTrivialDestructor() {} |
| 79 | }; |
| 80 | |
| 81 | class Trivial { |
| 82 | public: |
| 83 | Trivial() = default; |
| 84 | Trivial(int a) {} |
| 85 | }; |
| 86 | |
| 87 | int side_effect() { |
| 88 | return 42; |
| 89 | } |
| 90 | |
| 91 | class A { |
| 92 | public: |
| 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 | |
| 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: |
| 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> |
| 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; |
| 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 { |
| 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 { |
| 230 | 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 { |
| 237 | B() : a(A()) {} |
| 238 | B(char) {} |
| 239 | 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: |
| 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 | |