1 // RUN: %check_clang_tidy %s readability-convert-member-functions-to-static %t 2 3 class DoNotMakeEmptyStatic { emptyMethod()4 void emptyMethod() {} 5 void empty_method_out_of_line(); 6 }; 7 empty_method_out_of_line()8void DoNotMakeEmptyStatic::empty_method_out_of_line() {} 9 10 class A { 11 int field; 12 const int const_field; 13 static int static_field; 14 no_use()15 void no_use() { 16 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'no_use' can be made static 17 // CHECK-FIXES: {{^}} static void no_use() { 18 int i = 1; 19 } 20 read_field()21 int read_field() { 22 return field; 23 } 24 write_field()25 void write_field() { 26 field = 1; 27 } 28 call_non_const_member()29 int call_non_const_member() { return read_field(); } 30 call_static_member()31 int call_static_member() { 32 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'call_static_member' can be made static 33 // CHECK-FIXES: {{^}} static int call_static_member() { 34 already_static(); 35 } 36 read_static()37 int read_static() { 38 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'read_static' can be made static 39 // CHECK-FIXES: {{^}} static int read_static() { 40 return static_field; 41 } write_static()42 void write_static() { 43 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'write_static' can be made static 44 // CHECK-FIXES: {{^}} static void write_static() { 45 static_field = 1; 46 } 47 already_static()48 static int already_static() { return static_field; } 49 already_const() const50 int already_const() const { return field; } 51 already_const_convert_to_static() const52 int already_const_convert_to_static() const { 53 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'already_const_convert_to_static' can be made static 54 // CHECK-FIXES: {{^}} static int already_const_convert_to_static() { 55 return static_field; 56 } 57 58 static int out_of_line_already_static(); 59 60 void out_of_line_call_static(); 61 // CHECK-FIXES: {{^}} static void out_of_line_call_static(); 62 int out_of_line_const_to_static() const; 63 // CHECK-FIXES: {{^}} static int out_of_line_const_to_static() ; 64 }; 65 out_of_line_already_static()66int A::out_of_line_already_static() { return 0; } 67 out_of_line_call_static()68void A::out_of_line_call_static() { 69 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: method 'out_of_line_call_static' can be made static 70 // CHECK-FIXES: {{^}}void A::out_of_line_call_static() { 71 already_static(); 72 } 73 out_of_line_const_to_static() const74int A::out_of_line_const_to_static() const { 75 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'out_of_line_const_to_static' can be made static 76 // CHECK-FIXES: {{^}}int A::out_of_line_const_to_static() { 77 return 0; 78 } 79 80 struct KeepVirtual { fKeepVirtual81 virtual int f() { return 0; } hKeepVirtual82 virtual int h() const { return 0; } 83 }; 84 85 struct KeepVirtualDerived : public KeepVirtual { fKeepVirtualDerived86 int f() { return 0; } hKeepVirtualDerived87 int h() const override { return 0; } 88 }; 89 90 // Don't add 'static' to special member functions and operators. 91 struct KeepSpecial { KeepSpecialKeepSpecial92 KeepSpecial() { int L = 0; } ~KeepSpecialKeepSpecial93 ~KeepSpecial() { int L = 0; } operator +KeepSpecial94 int operator+() { return 0; } operator intKeepSpecial95 operator int() { return 0; } 96 }; 97 KeepLambdas()98void KeepLambdas() { 99 using FT = int (*)(); 100 auto F = static_cast<FT>([]() { return 0; }); 101 auto F2 = []() { return 0; }; 102 } 103 104 template <class Base> 105 struct KeepWithTemplateBase : public Base { 106 int i; 107 // We cannot make these methods static because they might need to override 108 // a function from Base. static_fKeepWithTemplateBase109 int static_f() { return 0; } 110 }; 111 112 template <class T> 113 struct KeepTemplateClass { 114 int i; 115 // We cannot make these methods static because a specialization 116 // might use *this differently. static_fKeepTemplateClass117 int static_f() { return 0; } 118 }; 119 120 struct KeepTemplateMethod { 121 int i; 122 // We cannot make these methods static because a specialization 123 // might use *this differently. 124 template <class T> static_fKeepTemplateMethod125 static int static_f() { return 0; } 126 }; 127 instantiate()128void instantiate() { 129 struct S {}; 130 KeepWithTemplateBase<S> I1; 131 I1.static_f(); 132 133 KeepTemplateClass<int> I2; 134 I2.static_f(); 135 136 KeepTemplateMethod I3; 137 I3.static_f<int>(); 138 } 139 140 struct Trailing { gTrailing141 auto g() const -> int { 142 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'g' can be made static 143 // CHECK-FIXES: {{^}} static auto g() -> int { 144 return 0; 145 } 146 volTrailing147 void vol() volatile { 148 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'vol' can be made static 149 return; 150 } 151 refTrailing152 void ref() const & { 153 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'ref' can be made static 154 return; 155 } refrefTrailing156 void refref() const && { 157 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'refref' can be made static 158 return; 159 } 160 restrTrailing161 void restr() __restrict { 162 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'restr' can be made static 163 return; 164 } 165 }; 166 167 struct UnevaluatedContext { fUnevaluatedContext168 void f() { sizeof(this); } 169 170 void noex() noexcept(noexcept(this)); 171 }; 172 173 struct LambdaCapturesThis { 174 int Field; 175 explicitCaptureLambdaCapturesThis176 int explicitCapture() { 177 return [this]() { return Field; }(); 178 } 179 implicitCaptureLambdaCapturesThis180 int implicitCapture() { 181 return [&]() { return Field; }(); 182 } 183 }; 184 185 struct NoFixitInMacro { 186 #define CONST const no_use_macro_constNoFixitInMacro187 int no_use_macro_const() CONST { 188 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'no_use_macro_const' can be made static 189 return 0; 190 } 191 192 #define ADD_CONST(F) F const ADD_CONSTNoFixitInMacro193 int ADD_CONST(no_use_macro2()) { 194 return 0; 195 } 196 197 #define FUN no_use_macro() 198 int i; 199 int FUN { 200 return i; 201 } 202 203 #define T(FunctionName, Keyword) \ 204 Keyword int FunctionName() { return 0; } 205 #define EMPTY 206 T(A, EMPTY) 207 T(B, static) 208 209 #define T2(FunctionName) \ 210 int FunctionName() { return 0; } 211 T2(A2) 212 213 #define VOLATILE volatile 214 void volatileMacro() VOLATILE { 215 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'volatileMacro' can be made static 216 return; 217 } 218 }; 219