brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · 72a8e36 Raw
339 lines · cpp
1// RUN: %check_clang_tidy %s readability-make-member-function-const %t2 3struct Str {4  void const_method() const;5  void non_const_method();6};7 8namespace Diagnose {9struct A;10 11void free_const_use(const A *);12void free_const_use(const A &);13 14struct A {15  int M;16  const int ConstM;17  struct {18    int M;19  } Struct;20  Str S;21  Str &Sref;22 23  void already_const() const;24 25  int read_field() {26    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'read_field' can be made const27    // CHECK-FIXES: int read_field() const {28    return M;29  }30 31  int read_struct_field() {32    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'read_struct_field' can be made const33    // CHECK-FIXES: int read_struct_field() const {34    return Struct.M;35  }36 37  int read_const_field() {38    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'read_const_field' can be made const39    // CHECK-FIXES: int read_const_field() const {40    return ConstM;41  }42 43  int read_fields_in_parentheses() {44    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'read_fields_in_parentheses' can be made const45    // CHECK-FIXES: int read_fields_in_parentheses() const {46    return (this)->M + (((((Struct.M))))) + ((this->ConstM));47  }48 49  void call_const_member() {50    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'call_const_member' can be made const51    // CHECK-FIXES: void call_const_member() const {52    already_const();53  }54 55  void call_const_member_on_public_field() {56    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'call_const_member_on_public_field' can be made const57    // CHECK-FIXES: void call_const_member_on_public_field() const {58    S.const_method();59  }60 61  void call_const_member_on_public_field_ref() {62    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'call_const_member_on_public_field_ref' can be made const63    // CHECK-FIXES: void call_const_member_on_public_field_ref() const {64    Sref.const_method();65  }66 67  const Str &return_public_field_ref() {68    // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: method 'return_public_field_ref' can be made const69    // CHECK-FIXES: const Str &return_public_field_ref() const {70    return S;71  }72 73  const A *return_this_const() {74    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: method 'return_this_const' can be made const75    // CHECK-FIXES: const A *return_this_const() const {76    return this;77  }78 79  const A &return_this_const_ref() {80    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: method 'return_this_const_ref' can be made const81    // CHECK-FIXES: const A &return_this_const_ref() const {82    return *this;83  }84 85  void const_use() {86    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'const_use' can be made const87    // CHECK-FIXES: void const_use() const {88    free_const_use(this);89  }90 91  void const_use_ref() {92    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'const_use_ref' can be made const93    // CHECK-FIXES: void const_use_ref() const {94    free_const_use(*this);95  }96 97  auto trailingReturn() -> int {98    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'trailingReturn' can be made const99    // CHECK-FIXES: auto trailingReturn() const -> int {100    return M;101  }102 103  int volatileFunction() volatile {104    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'volatileFunction' can be made const105    // CHECK-FIXES: int volatileFunction() const volatile {106    return M;107  }108 109  int restrictFunction() __restrict {110    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'restrictFunction' can be made const111    // CHECK-FIXES: int restrictFunction() const __restrict {112    return M;113  }114 115  int refFunction() & {116    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'refFunction' can be made const117    // CHECK-FIXES: int refFunction() const & {118    return M;119  }120 121  void out_of_line_call_const();122  // CHECK-FIXES: void out_of_line_call_const() const;123};124 125void A::out_of_line_call_const() {126  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: method 'out_of_line_call_const' can be made const127  // CHECK-FIXES: void A::out_of_line_call_const() const {128  already_const();129}130} // namespace Diagnose131 132namespace Keep {133struct Keep;134void free_non_const_use(Keep *);135void free_non_const_use(Keep &);136 137struct Keep {138private:139  void private_const_method() const;140  Str PrivateS;141  Str *Sptr;142  Str &Sref;143 144public:145  int M;146  Str S;147 148  void keepTrivial() {}149 150  // See readability-convert-member-functions-to-static instead.151  void keepStatic() { int I = 0; }152 153  const int *keepConstCast() const;154  int *keepConstCast() { // Needs to stay non-const.155    return const_cast<int *>(static_cast<const Keep *>(this)->keepConstCast());156  }157 158  void non_const_use() { free_non_const_use(this); }159  void non_const_use_ref() { free_non_const_use(*this); }160 161  Keep *return_this() {162    return this;163  }164 165  Keep &return_this_ref() {166    return *this;167  }168 169  void escape_this() {170    Keep *Escaped = this;171  }172 173  void call_private_const_method() {174    private_const_method();175  }176 177  int keepConst() const { return M; }178 179  virtual int keepVirtual() { return M; }180 181  void writeField() {182    M = 1;183  }184 185  void callNonConstMember() { writeField(); }186 187  void call_non_const_member_on_field() { S.non_const_method(); }188 189  void call_const_member_on_private_field() {190    // Technically, this method could be const-qualified,191    // but it might not be logically const.192    PrivateS.const_method();193  }194 195  const Str &return_private_field_ref() {196    // Technically, this method could be const-qualified,197    // but it might not be logically const.198    return PrivateS;199  }200 201  void call_non_const_member_on_pointee() {202    Sptr->non_const_method();203  }204 205  void call_const_member_on_pointee() {206    // Technically, this method could be const-qualified,207    // but it might not be logically const.208    Sptr->const_method();209  }210 211  Str *return_pointer() {212    // Technically, this method could be const-qualified,213    // but it might not be logically const.214    return Sptr;215  }216 217  const Str *return_const_pointer() {218    // Technically, this method could be const-qualified,219    // but it might not be logically const.220    return Sptr;221  }222 223  void call_non_const_member_on_ref() {224    Sref.non_const_method();225  }226 227  void escaped_private_field() {228    const auto &Escaped = Sref;229  }230 231  Str &return_field_ref() {232    // Technically, this method could be const-qualified,233    // but it might not be logically const.234    return Sref;235  }236 237  const Str &return_field_const_ref() {238    // Technically, this method could be const-qualified,239    // but it might not be logically const.240    return Sref;241  }242};243 244struct KeepVirtualDerived : public Keep {245  int keepVirtual() { return M; }246};247 248void KeepLambdas() {249  auto F = +[]() { return 0; };250  auto F2 = []() { return 0; };251}252 253template <class Base>254struct KeepWithDependentBase : public Base {255  int M;256  // We cannot make this method const because it might need to override257  // a function from Base.258  int const_f() { return M; }259};260 261template <class T>262struct KeepClassTemplate {263  int M;264  // We cannot make this method const because a specialization265  // might use *this differently.266  int const_f() { return M; }267};268 269struct KeepMemberFunctionTemplate {270  int M;271  // We cannot make this method const because a specialization272  // might use *this differently.273  template <class T>274  int const_f() { return M; }275};276 277void instantiate() {278  struct S {};279  KeepWithDependentBase<S> I1;280  I1.const_f();281 282  KeepClassTemplate<int> I2;283  I2.const_f();284 285  KeepMemberFunctionTemplate I3;286  I3.const_f<int>();287}288 289struct NoFixitInMacro {290  int M;291 292#define FUN const_use_macro()293  int FUN {294    return M;295  }296 297#define T(FunctionName, Keyword) \298  int FunctionName() Keyword { return M; }299#define EMPTY300  T(A, EMPTY)301  T(B, const)302 303#define T2(FunctionName) \304  int FunctionName() { return M; }305  T2(A2)306};307 308// Real-world code, see clang::ObjCInterfaceDecl.309class DataPattern {310  int &data() const;311 312public:313  const int &get() const {314    return const_cast<DataPattern *>(this)->get();315  }316 317  // This member function must stay non-const, even though318  // it only calls other private const member functions.319  int &get() {320    return data();321  }322 323  void set() {324    data() = 42;325  }326};327 328struct MemberFunctionPointer {329  void call_non_const(void (MemberFunctionPointer::*FP)()) {330    (this->*FP)();331  }332 333  void call_const(void (MemberFunctionPointer::*FP)() const) {334    (this->*FP)();335  }336};337 338} // namespace Keep339