brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.6 KiB · 4cef7f4 Raw
1018 lines · cpp
1// RUN: %check_clang_tidy %s misc-const-correctness %t -- \2// RUN:   -config="{CheckOptions: {\3// RUN:     misc-const-correctness.TransformValues: true, \4// RUN:     misc-const-correctness.WarnPointersAsValues: false, \5// RUN:     misc-const-correctness.WarnPointersAsPointers: false, \6// RUN:     misc-const-correctness.TransformPointersAsValues: false \7// RUN:   }}" -- -fno-delayed-template-parsing -fexceptions8 9// ------- Provide test samples for primitive builtins ---------10// - every 'p_*' variable is a 'potential_const_*' variable11// - every 'np_*' variable is a 'non_potential_const_*' variable12 13bool global;14char np_global = 0; // globals can't be known to be const15 16// FIXME: 'static' globals are not matched right now. They could be analyzed but aren't right now.17static int p_static_global = 42;18 19namespace foo {20int scoped;21float np_scoped = 1; // namespace variables are like globals22} // namespace foo23 24// FIXME: Similary to 'static' globals, anonymous globals are not matched and analyzed.25namespace {26int np_anonymous_global;27int p_anonymous_global = 43;28} // namespace29 30// Lambdas should be ignored, because they do not follow the normal variable31// semantic (e.g. the type is only known to the compiler).32void lambdas() {33  auto Lambda = [](int i) { return i < 0; };34}35 36void some_function(double, wchar_t);37 38void some_function(double np_arg0, wchar_t np_arg1) {39  int p_local0 = 2;40  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'41  // CHECK-FIXES: int const p_local0 = 2;42 43  int np_local0;44  const int np_local1 = 42;45 46  unsigned int np_local2 = 3;47  np_local2 <<= 4;48 49  int np_local3 = 4;50  ++np_local3;51  int np_local4 = 4;52  np_local4++;53 54  int np_local5 = 4;55  --np_local5;56  int np_local6 = 4;57  np_local6--;58}59 60int function_try_block() try {61  int p_local0 = 0;62  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'63  // CHECK-FIXES: int const p_local0 = 0;64  return p_local0;65} catch (...) {66  return 0;67}68 69void nested_scopes() {70  int p_local0 = 2;71  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'72  // CHECK-FIXES: int const p_local0 = 2;73  int np_local0 = 42;74 75  {76    int p_local1 = 42;77    // CHECK-MESSAGES: [[@LINE-1]]:5: warning: variable 'p_local1' of type 'int' can be declared 'const'78    // CHECK-FIXES: int const p_local1 = 42;79    np_local0 *= 2;80  }81}82 83void ignore_reference_to_pointers() {84  int *np_local0 = nullptr;85  int *&np_local1 = np_local0;86}87 88void some_lambda_environment_capture_all_by_reference(double np_arg0) {89  int np_local0 = 0;90  int p_local0 = 1;91  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'92  // CHECK-FIXES: int const p_local0 = 1;93 94  int np_local2;95  const int np_local3 = 2;96 97  // Capturing all variables by reference prohibits making them const.98  [&]() { ++np_local0; };99 100  int p_local1 = 0;101  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'102  // CHECK-FIXES: int const p_local1 = 0;103}104 105void some_lambda_environment_capture_all_by_value(double np_arg0) {106  int np_local0 = 0;107  int p_local0 = 1;108  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'109  // CHECK-FIXES: int const p_local0 = 1;110 111  int np_local1;112  const int np_local2 = 2;113 114  // Capturing by value has no influence on them.115  [=]() { (void)p_local0; };116 117  np_local0 += 10;118}119 120void function_inout_pointer(int *inout);121void function_in_pointer(const int *in);122 123void some_pointer_taking(int *out) {124  int np_local0 = 42;125  const int *const p0_np_local0 = &np_local0;126  int *const p1_np_local0 = &np_local0;127 128  int np_local1 = 42;129  const int *const p0_np_local1 = &np_local1;130  int *const p1_np_local1 = &np_local1;131  *p1_np_local0 = 43;132 133  int np_local2 = 42;134  function_inout_pointer(&np_local2);135 136  // Prevents const.137  int np_local3 = 42;138  out = &np_local3; // This returns and invalid address, its just about the AST139 140  int p_local1 = 42;141  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'142  // CHECK-FIXES: int const p_local1 = 42;143  const int *const p0_p_local1 = &p_local1;144 145  int p_local2 = 42;146  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'int' can be declared 'const'147  // CHECK-FIXES: int const p_local2 = 42;148  function_in_pointer(&p_local2);149}150 151void function_inout_ref(int &inout);152void function_in_ref(const int &in);153 154void some_reference_taking() {155  int np_local0 = 42;156  const int &r0_np_local0 = np_local0;157  int &r1_np_local0 = np_local0;158  r1_np_local0 = 43;159  const int &r2_np_local0 = r1_np_local0;160 161  int np_local1 = 42;162  function_inout_ref(np_local1);163 164  int p_local0 = 42;165  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'166  // CHECK-FIXES: int const p_local0 = 42;167  const int &r0_p_local0 = p_local0;168 169  int p_local1 = 42;170  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'171  // CHECK-FIXES: int const p_local1 = 42;172  function_in_ref(p_local1);173}174 175double *non_const_pointer_return() {176  double p_local0 = 0.0;177  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const'178  // CHECK-FIXES: double const p_local0 = 0.0;179  double np_local0 = 24.4;180 181  return &np_local0;182}183 184const double *const_pointer_return() {185  double p_local0 = 0.0;186  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const'187  // CHECK-FIXES: double const p_local0 = 0.0;188  double p_local1 = 24.4;189  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const'190  // CHECK-FIXES: double const p_local1 = 24.4;191  return &p_local1;192}193 194// Also see const-correctness-values.cpp-before-cxx23.cpp for `non_const_ref_return` and `return_non_const_pointer_ref`195const double &const_ref_return() {196  double p_local0 = 0.0;197  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double' can be declared 'const'198  // CHECK-FIXES: double const p_local0 = 0.0;199  double p_local1 = 24.4;200  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const'201  // CHECK-FIXES: double const p_local1 = 24.4;202  return p_local1;203}204 205void overloaded_arguments(const int &in);206void overloaded_arguments(int &inout);207void overloaded_arguments(const int *in);208void overloaded_arguments(int *inout);209 210void function_calling() {211  int np_local0 = 42;212  overloaded_arguments(np_local0);213 214  const int np_local1 = 42;215  overloaded_arguments(np_local1);216 217  int np_local2 = 42;218  overloaded_arguments(&np_local2);219 220  const int np_local3 = 42;221  overloaded_arguments(&np_local3);222}223 224template <typename T>225void define_locals(T np_arg0, T &np_arg1, int np_arg2) {226  T np_local0 = 0;227  np_local0 += np_arg0 * np_arg1;228 229  T np_local1 = 42;230  np_local0 += np_local1;231 232  // Used as argument to an overloaded function with const and non-const.233  T np_local2 = 42;234  overloaded_arguments(np_local2);235 236  int np_local4 = 42;237  // non-template values are ok still.238  int p_local0 = 42;239  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'240  // CHECK-FIXES: int const p_local0 = 42;241  np_local4 += p_local0;242}243 244template <typename T>245void more_template_locals() {246  const T np_local0 = {};247  auto np_local1 = T{};248  T &np_local2 = np_local1;249  T *np_local_ptr = &np_local1;250 251  const auto np_local3 = T{};252  // FIXME: False positive, the reference points to a template type and needs253  // to be excluded from analysis, but somehow isn't (matchers don't work)254  auto &np_local4 = np_local3;255 256  const auto *np_local5 = &np_local3;257  auto *np_local6 = &np_local1;258 259  using TypedefToTemplate = T;260  TypedefToTemplate np_local7{};261  // FIXME: False positive, the reference points to a template type and needs262  // to be excluded from analysis, but somehow isn't (matchers don't work)263  // auto &np_local8 = np_local7;264  const auto &np_local9 = np_local7;265  auto np_local10 = np_local7;266  auto *np_local11 = &np_local10;267  const auto *const np_local12 = &np_local10;268 269  // FIXME: False positive, the reference points to a template type and needs270  // to be excluded from analysis, but somehow isn't (matchers don't work)271  // TypedefToTemplate &np_local13 = np_local7;272  TypedefToTemplate *np_local14 = &np_local7;273}274 275void template_instantiation() {276  const int np_local0 = 42;277  int np_local1 = 42;278 279  define_locals(np_local0, np_local1, np_local0);280  define_locals(np_local1, np_local1, np_local1);281  more_template_locals<int>();282}283 284struct ConstNonConstClass {285  ConstNonConstClass();286  ConstNonConstClass(double &np_local0);287  double nonConstMethod() { return 0; }288  double constMethod() const { return 0; }289  double modifyingMethod(double &np_arg0) const;290 291  double NonConstMember;292  const double ConstMember;293 294  double &NonConstMemberRef;295  const double &ConstMemberRef;296 297  double *NonConstMemberPtr;298  const double *ConstMemberPtr;299};300 301void direct_class_access() {302  ConstNonConstClass np_local0;303 304  np_local0.constMethod();305  np_local0.nonConstMethod();306 307  ConstNonConstClass p_local0;308  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass' can be declared 'const'309  // CHECK-FIXES: ConstNonConstClass const p_local0;310  p_local0.constMethod();311 312  ConstNonConstClass p_local1;313  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'ConstNonConstClass' can be declared 'const'314  // CHECK-FIXES: ConstNonConstClass const p_local1;315  double np_local1;316  p_local1.modifyingMethod(np_local1);317 318  double np_local2;319  ConstNonConstClass p_local2(np_local2);320  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'ConstNonConstClass' can be declared 'const'321  // CHECK-FIXES: ConstNonConstClass const p_local2(np_local2);322 323  ConstNonConstClass np_local3;324  np_local3.NonConstMember = 42.;325 326  ConstNonConstClass np_local4;327  np_local4.NonConstMemberRef = 42.;328 329  ConstNonConstClass p_local3;330  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'ConstNonConstClass' can be declared 'const'331  // CHECK-FIXES: ConstNonConstClass const p_local3;332  const double val0 = p_local3.NonConstMember;333  const double val1 = p_local3.NonConstMemberRef;334  const double val2 = *p_local3.NonConstMemberPtr;335 336  ConstNonConstClass p_local4;337  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local4' of type 'ConstNonConstClass' can be declared 'const'338  // CHECK-FIXES: ConstNonConstClass const p_local4;339  *np_local4.NonConstMemberPtr = 42.;340}341 342void class_access_array() {343  ConstNonConstClass np_local0[2];344  np_local0[0].constMethod();345  np_local0[1].constMethod();346  np_local0[1].nonConstMethod();347 348  ConstNonConstClass p_local0[2];349  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass[2]' can be declared 'const'350  // CHECK-FIXES: ConstNonConstClass const p_local0[2];351  p_local0[0].constMethod();352  np_local0[1].constMethod();353}354 355struct OperatorsAsConstAsPossible {356  OperatorsAsConstAsPossible &operator+=(const OperatorsAsConstAsPossible &rhs);357  OperatorsAsConstAsPossible operator+(const OperatorsAsConstAsPossible &rhs) const;358};359 360struct NonConstOperators {361};362NonConstOperators operator+(NonConstOperators &lhs, NonConstOperators &rhs);363NonConstOperators operator-(NonConstOperators lhs, NonConstOperators rhs);364 365void internal_operator_calls() {366  OperatorsAsConstAsPossible np_local0;367  OperatorsAsConstAsPossible np_local1;368  OperatorsAsConstAsPossible p_local0;369  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'OperatorsAsConstAsPossible' can be declared 'const'370  // CHECK-FIXES: OperatorsAsConstAsPossible const p_local0;371  OperatorsAsConstAsPossible p_local1;372  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'OperatorsAsConstAsPossible' can be declared 'const'373  // CHECK-FIXES: OperatorsAsConstAsPossible const p_local1;374 375  np_local0 += p_local0;376  np_local1 = p_local0 + p_local1;377 378  NonConstOperators np_local2;379  NonConstOperators np_local3;380  NonConstOperators np_local4;381 382  np_local2 = np_local3 + np_local4;383 384  NonConstOperators p_local2;385  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'NonConstOperators' can be declared 'const'386  // CHECK-FIXES: NonConstOperators const p_local2;387  NonConstOperators p_local3 = p_local2 - p_local2;388  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'NonConstOperators' can be declared 'const'389  // CHECK-FIXES: NonConstOperators const p_local3 = p_local2 - p_local2;390}391 392struct MyVector {393  double *begin();394  const double *begin() const;395 396  double *end();397  const double *end() const;398 399  double &operator[](int index);400  double operator[](int index) const;401 402  double values[100];403};404 405void vector_usage() {406  double np_local0[10];407  np_local0[5] = 42.;408 409  MyVector np_local1;410  np_local1[5] = 42.;411 412  double p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};413  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double[10]' can be declared 'const'414  // CHECK-FIXES: double const p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};415  double p_local1 = p_local0[5];416  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double' can be declared 'const'417  // CHECK-FIXES: double const p_local1 = p_local0[5];418 419  // The following subscript calls surprisingly choose the non-const operator420  // version.421  MyVector np_local2;422  double p_local2 = np_local2[42];423  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'double' can be declared 'const'424  // CHECK-FIXES: double const p_local2 = np_local2[42];425 426  MyVector np_local3;427  const double np_local4 = np_local3[42];428 429  // This subscript results in const overloaded operator.430  const MyVector np_local5{};431  double p_local3 = np_local5[42];432  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'double' can be declared 'const'433  // CHECK-FIXES: double const p_local3 = np_local5[42];434}435 436void const_handle(const double &np_local0);437void const_handle(const double *np_local0);438 439void non_const_handle(double &np_local0);440void non_const_handle(double *np_local0);441 442void handle_from_array() {443  // Non-const handle from non-const array forbids declaring the array as const444  double np_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};445  double *p_local0 = &np_local0[1]; // Could be `double *const`, but warning deactivated by default446 447  double np_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};448  double &non_const_ref = np_local1[1];449  non_const_ref = 42.;450 451  double np_local2[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};452  double *np_local3;453  np_local3 = &np_local2[5];454 455  double np_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};456  non_const_handle(np_local4[2]);457  double np_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};458  non_const_handle(&np_local5[2]);459 460  // Constant handles are ok461  double p_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};462  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'double[10]' can be declared 'const'463  // CHECK-FIXES: double const p_local1[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};464  const double *p_local2 = &p_local1[2]; // Could be `const double *const`, but warning deactivated by default465 466  double p_local3[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};467  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'double[10]' can be declared 'const'468  // CHECK-FIXES: double const p_local3[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};469  const double &const_ref = p_local3[2];470 471  double p_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};472  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local4' of type 'double[10]' can be declared 'const'473  // CHECK-FIXES: double const p_local4[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};474  const double *const_ptr;475  const_ptr = &p_local4[2];476 477  double p_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};478  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local5' of type 'double[10]' can be declared 'const'479  // CHECK-FIXES: double const p_local5[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};480  const_handle(p_local5[2]);481  double p_local6[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};482  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local6' of type 'double[10]' can be declared 'const'483  // CHECK-FIXES: double const p_local6[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.};484  const_handle(&p_local6[2]);485}486 487void range_for() {488  int np_local0[2] = {1, 2};489  for (int &non_const_ref : np_local0) {490    non_const_ref = 42;491  }492 493  int np_local1[2] = {1, 2};494  for (auto &non_const_ref : np_local1) {495    non_const_ref = 43;496  }497 498  int np_local2[2] = {1, 2};499  for (auto &&non_const_ref : np_local2) {500    non_const_ref = 44;501  }502 503  int *np_local3[2] = {&np_local0[0], &np_local0[1]};504  for (int *non_const_ptr : np_local3) {505    *non_const_ptr = 45;506  }507 508  // FIXME same as above, but silenced509  int *const np_local4[2] = {&np_local0[0], &np_local0[1]};510  for (auto *non_const_ptr : np_local4) {511    *non_const_ptr = 46;512  }513 514  int p_local0[2] = {1, 2};515  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int[2]' can be declared 'const'516  // CHECK-FIXES: int const p_local0[2] = {1, 2};517  for (int value : p_local0) {518    // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'value' of type 'int' can be declared 'const'519    // CHECK-FIXES: for (int const value : p_local0) {520  }521 522  int p_local1[2] = {1, 2};523  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int[2]' can be declared 'const'524  // CHECK-FIXES: int const p_local1[2] = {1, 2};525  for (const int &const_ref : p_local1) {526  }527}528 529void arrays_of_pointers_are_ignored() {530  int *np_local0[2] = {nullptr, nullptr};531 532  using intPtr = int*;533  intPtr np_local1[2] = {nullptr, nullptr};534}535 536inline void *operator new(decltype(sizeof(void *)), void *p) { return p; }537 538struct Value {539};540void placement_new() {541  Value Mem;542  Value *V = new (&Mem) Value;543}544 545struct ModifyingConversion {546  operator int() { return 15; }547};548struct NonModifyingConversion {549  operator int() const { return 15; }550};551void conversion_operators() {552  ModifyingConversion np_local0;553  NonModifyingConversion p_local0;554  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'NonModifyingConversion' can be declared 'const'555  // CHECK-FIXES: NonModifyingConversion const p_local0;556 557  int np_local1 = np_local0;558  np_local1 = p_local0;559}560 561void casts() {562  decltype(sizeof(void *)) p_local0 = 42;563  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'decltype(sizeof(void *))'564  // CHECK-FIXES: decltype(sizeof(void *)) const p_local0 = 42;565  auto np_local0 = reinterpret_cast<void *>(p_local0);566  np_local0 = nullptr;567 568  int p_local1 = 43;569  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const'570  // CHECK-FIXES: int const p_local1 = 43;571  short p_local2 = static_cast<short>(p_local1);572  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local2' of type 'short' can be declared 'const'573  // CHECK-FIXES: short const p_local2 = static_cast<short>(p_local1);574 575  int np_local1 = p_local2;576  int &np_local2 = static_cast<int &>(np_local1);577  np_local2 = 5;578}579 580void ternary_operator() {581  int np_local0 = 1, np_local1 = 2;582  int &np_local2 = true ? np_local0 : np_local1;583  np_local2 = 2;584 585  int p_local0 = 3, np_local3 = 5;586  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'587  // CHECK-NOT-FIXES: int const p_local0 = 3, np_local3 = 5;588  const int &np_local4 = true ? p_local0 : ++np_local3;589 590  int np_local5[3] = {1, 2, 3};591  int &np_local6 = np_local5[1] < np_local5[2] ? np_local5[0] : np_local5[2];592  np_local6 = 42;593 594  int np_local7[3] = {1, 2, 3};595  int *np_local8 = np_local7[1] < np_local7[2] ? &np_local7[0] : &np_local7[2];596  *np_local8 = 42;597}598 599// Taken from libcxx/include/type_traits and improved readability.600template <class Tp, Tp v>601struct integral_constant {602  static constexpr const Tp value = v;603  using value_type = Tp;604  using type = integral_constant;605  constexpr operator value_type() const noexcept { return value; }606  constexpr value_type operator()() const noexcept { return value; }607};608 609template <typename T>610struct is_integral : integral_constant<bool, false> {};611template <>612struct is_integral<int> : integral_constant<bool, true> {};613 614template <typename T>615struct not_integral : integral_constant<bool, false> {};616template <>617struct not_integral<double> : integral_constant<bool, true> {};618 619template <bool, typename Tp = void>620struct enable_if {};621 622template <typename Tp>623struct enable_if<true, Tp> { using type = Tp; };624 625template <typename T>626struct TMPClass {627  T alwaysConst() const { return T{}; }628 629  template <typename T2 = T, typename = typename enable_if<is_integral<T2>::value>::type>630  T sometimesConst() const { return T{}; }631 632  template <typename T2 = T, typename = typename enable_if<not_integral<T2>::value>::type>633  T sometimesConst() { return T{}; }634};635 636void meta_type() {637  TMPClass<int> p_local0;638  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'TMPClass<int>' can be declared 'const'639  // CHECK-FIXES: TMPClass<int> const p_local0;640  p_local0.alwaysConst();641  p_local0.sometimesConst();642 643  TMPClass<double> p_local1;644  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'TMPClass<double>' can be declared 'const'645  // CHECK-FIXES: TMPClass<double> const p_local1;646  p_local1.alwaysConst();647 648  TMPClass<double> np_local0;649  np_local0.alwaysConst();650  np_local0.sometimesConst();651}652 653// This test is the essence from llvm/lib/Support/MemoryBuffer.cpp at line 450654template <typename T>655struct to_construct : T {656  to_construct(int &j) {}657};658template <typename T>659void placement_new_in_unique_ptr() {660  int p_local0 = 42;661  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'662  // CHECK-FIXES: int const p_local0 = 42;663  int np_local0 = p_local0;664  new to_construct<T>(np_local0);665}666 667struct stream_obj {};668stream_obj &operator>>(stream_obj &o, unsigned &foo);669void input_operator() {670  stream_obj np_local0;671  unsigned np_local1 = 42;672  np_local0 >> np_local1;673}674 675struct stream_obj_template {};676template <typename IStream>677IStream &operator>>(IStream &o, unsigned &foo);678 679template <typename Stream>680void input_operator_template() {681  Stream np_local0;682  unsigned np_local1 = 42;683  np_local0 >> np_local1;684}685 686// Test bit fields687struct HardwareRegister {688  unsigned field : 5;689  unsigned : 7;690  unsigned another : 20;691};692 693void TestRegisters() {694  HardwareRegister np_reg0;695  np_reg0.field = 3;696 697  HardwareRegister p_reg1{3, 22};698  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_reg1' of type 'HardwareRegister' can be declared 'const'699  // CHECK-FIXES: HardwareRegister const p_reg1{3, 22};700  const unsigned p_val = p_reg1.another;701}702 703struct IntWrapper {704  IntWrapper &operator=(unsigned value) { return *this; }705  template <typename Istream>706  friend Istream &operator>>(Istream &is, IntWrapper &rhs);707};708struct IntMaker {709  friend IntMaker &operator>>(IntMaker &, unsigned &);710};711template <typename Istream>712Istream &operator>>(Istream &is, IntWrapper &rhs) {713  unsigned np_local0 = 0;714  is >> np_local0;715  return is;716}717 718struct Actuator {719  int actuations;720};721struct Sensor {722  int observations;723};724struct System : public Actuator, public Sensor {725};726int some_computation(int arg);727int test_inheritance() {728  System np_sys;729  np_sys.actuations = 5;730  return some_computation(np_sys.actuations);731}732struct AnotherActuator : Actuator {733};734Actuator &test_return_polymorphic() {735  static AnotherActuator np_local0;736  return np_local0;737}738 739using f_signature = int *(*)(int &);740int *my_alloc(int &size) { return new int[size]; }741struct A {742  int f(int &i) { return i + 1; }743  int (A::*x)(int &);744};745void f() {746  int p_local0 = 42;747  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'748  // CHECK-FIXES: int const p_local0 = 42;749  int np_local0 = 42;750  f_signature action = my_alloc;751  action(np_local0);752  my_alloc(np_local0);753 754  int np_local1 = 42;755  A a;756  a.x = &A::f;757  (a.*(a.x))(np_local1);758}759 760struct nested_data {761  int more_data;762};763struct repro_assignment_to_reference {764  int my_data;765  nested_data nested;766};767void assignment_reference() {768  repro_assignment_to_reference np_local0{42};769  int &np_local1 = np_local0.my_data;770  np_local1++;771 772  repro_assignment_to_reference np_local2;773  int &np_local3 = np_local2.nested.more_data;774  np_local3++;775}776 777struct non_const_iterator {778  int data[42];779 780  int *begin() { return &data[0]; }781  int *end() { return &data[41]; }782};783 784// The problem is, that 'begin()' and 'end()' are not const overloaded, so785// they are always a mutation. If 'np_local1' is fixed to const it results in786// a compilation error.787void for_bad_iterators() {788  non_const_iterator np_local0;789  non_const_iterator &np_local1 = np_local0;790 791  for (int np_local2 : np_local1) {792    np_local2++;793  }794 795  non_const_iterator np_local3;796  for (int p_local0 : np_local3)797    // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local0' of type 'int' can be declared 'const'798    // CHECK-FIXES: for (int const p_local0 : np_local3)799    ;800 801  // Horrible code constructs...802  {803    non_const_iterator np_local4;804    np_local4.data[0]++;805    non_const_iterator np_local5;806    for (int p_local1 : np_local4, np_local5)807      // CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local1' of type 'int' can be declared 'const'808      // CHECK-FIXES: for (int const p_local1 : np_local4, np_local5)809      ;810 811    non_const_iterator np_local6;812    non_const_iterator np_local7;813    for (int p_local2 : 1 > 2 ? np_local6 : np_local7)814      // CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local2' of type 'int' can be declared 'const'815      // CHECK-FIXES: for (int const p_local2 : 1 > 2 ? np_local6 : np_local7)816      ;817 818    non_const_iterator np_local8;819    non_const_iterator np_local9;820    for (int p_local3 : 2 > 1 ? np_local8 : (np_local8, np_local9))821      // CHECK-MESSAGES: [[@LINE-1]]:10: warning: variable 'p_local3' of type 'int' can be declared 'const'822      // CHECK-FIXES: for (int const p_local3 : 2 > 1 ? np_local8 : (np_local8, np_local9))823      ;824  }825}826 827struct good_iterator {828  int data[3] = {1, 2, 3};829 830  int *begin() { return &data[0]; }831  int *end() { return &data[2]; }832  const int *begin() const { return &data[0]; }833  const int *end() const { return &data[2]; }834};835 836void good_iterators() {837  good_iterator p_local0;838  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'good_iterator' can be declared 'const'839  // CHECK-FIXES: good_iterator const p_local0;840  good_iterator &p_local1 = p_local0;841  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'good_iterator &' can be declared 'const'842  // CHECK-FIXES: good_iterator  const&p_local1 = p_local0;843 844  for (int p_local2 : p_local1) {845    // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local2' of type 'int' can be declared 'const'846    // CHECK-FIXES: for (int const p_local2 : p_local1) {847    (void)p_local2;848  }849 850  good_iterator p_local3;851  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local3' of type 'good_iterator' can be declared 'const'852  // CHECK-FIXES: good_iterator const p_local3;853  for (int p_local4 : p_local3)854    // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local4' of type 'int' can be declared 'const'855    // CHECK-FIXES: for (int const p_local4 : p_local3)856    ;857  good_iterator np_local1;858  for (int &np_local2 : np_local1)859    np_local2++;860}861 862void for_bad_iterators_array() {863  int np_local0[42];864  int(&np_local1)[42] = np_local0;865 866  for (int &np_local2 : np_local1) {867    np_local2++;868  }869}870void for_ok_iterators_array() {871  int np_local0[42];872  int(&p_local0)[42] = np_local0;873  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int (&)[42]' can be declared 'const'874  // CHECK-FIXES: int const(&p_local0)[42] = np_local0;875 876  for (int p_local1 : p_local0) {877    // CHECK-MESSAGES: [[@LINE-1]]:8: warning: variable 'p_local1' of type 'int' can be declared 'const'878    // CHECK-FIXES: for (int const p_local1 : p_local0) {879    (void)p_local1;880  }881}882 883void take_ref(int &);884void ternary_reference() {885  int np_local0 = 42;886  int np_local1 = 43;887  take_ref((np_local0 > np_local1 ? np_local0 : (np_local0, np_local1)));888}889 890void complex_usage() {891  int np_local0 = 42;892  int p_local0 = 42;893  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const'894  // CHECK-FIXES: int const p_local0 = 42;895  int np_local1 = 42;896  (np_local0 == p_local0 ? np_local0 : (p_local0, np_local1))++;897}898 899void vlas() {900  int N = 1; // Can't make N 'const' because VLAs make everything awful901  sizeof(int[++N]);902}903 904struct base {905  int member;906};907struct derived : base {};908struct another_struct {909  derived member;910};911void another_struct_f() {912  another_struct np_local0{};913  base &np_local1 = np_local0.member;914  np_local1.member++;915}916struct list_init {917  int &member;918};919void create_false_positive() {920  int np_local0 = 42;921  list_init p_local0 = {np_local0};922  // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local0' of type 'list_init' can be declared 'const'923  // CHECK-FIXES: list_init const p_local0 = {np_local0};924}925struct list_init_derived {926  base &member;927};928void list_init_derived_func() {929  derived np_local0;930  list_init_derived p_local0 = {np_local0};931  // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local0' of type 'list_init_derived' can be declared 'const'932  // CHECK-FIXES: list_init_derived const p_local0 = {np_local0};933}934template <typename L, typename R>935struct ref_pair {936  L &first;937  R &second;938};939template <typename T>940void list_init_template() {941  T np_local0{};942  ref_pair<T, T> p_local0 = {np_local0, np_local0};943}944void cast_in_class_hierarchy() {945  derived np_local0;946  base p_local1 = static_cast<base &>(np_local0);947  // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'p_local1' of type 'base' can be declared 'const'948  // CHECK-FIXES: base const p_local1 = static_cast<base &>(np_local0);949}950 951void function_ref_target(int);952using my_function_type = void (&)(int);953void func_references() {954  // Could be const, because the reference is not adjusted but adding that955  // has no effect and creates a compiler warning.956  my_function_type ptr = function_ref_target;957}958 959template <typename T>960T &return_ref() {961  static T global;962  return global;963}964template <typename T>965T *return_ptr() { return &return_ref<T>(); }966 967void auto_usage_variants() {968  auto auto_val0 = int{};969  // CHECK-FIXES-NOT: auto const auto_val0970  auto &auto_val1 = auto_val0;971  auto *auto_val2 = &auto_val0;972 973  auto auto_ref0 = return_ref<int>();974  // CHECK-FIXES-NOT: auto const auto_ref0975  auto &auto_ref1 = return_ref<int>(); // Bad976  auto *auto_ref2 = return_ptr<int>();977 978  auto auto_ptr0 = return_ptr<int>();979  // CHECK-FIXES-NOT: auto const auto_ptr0980  auto &auto_ptr1 = auto_ptr0;981  auto *auto_ptr2 = return_ptr<int>();982 983  using MyTypedef = int;984  auto auto_td0 = MyTypedef{};985  // CHECK-FIXES-NOT: auto const auto_td0986  auto &auto_td1 = auto_td0;987  auto *auto_td2 = &auto_td0;988}989 990using PointerToMemberFunction = int (Value::*)();991void member_pointer(Value &x, PointerToMemberFunction m) {992  Value &member_pointer_tmp = x;993  (member_pointer_tmp.*m)();994}995 996using PointerToConstMemberFunction = int (Value::*)() const;997void member_pointer_const(Value &x, PointerToConstMemberFunction m) {998  Value &member_pointer_tmp = x;999  // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'member_pointer_tmp' of type 'Value &' can be declared 'const'1000  (member_pointer_tmp.*m)();1001}1002 1003namespace gh127776_false_positive {1004template <class T> struct vector { T &operator[](int t); };1005template <typename T> void f() {1006  vector<int> x;1007  x[T{}] = 3;1008}1009} // namespace gh127776_false_positive1010 1011namespace gh132931_false_positive {1012using T = const int;1013void valid(int i) {1014  const int arr0[] = {1, 2, 3};1015  T arr1[] = {1, 2, 3};1016}1017} // namespace gh132931_false_positive1018