// RUN: %check_clang_tidy %s misc-const-correctness %t -- \ // RUN: -config="{CheckOptions: {\ // RUN: misc-const-correctness.TransformValues: true,\ // RUN: misc-const-correctness.WarnPointersAsValues: false, \ // RUN: misc-const-correctness.TransformPointersAsValues: false} \ // RUN: }" -- -fno-delayed-template-parsing bool global; char np_global = 0; // globals can't be known to be const namespace foo { int scoped; float np_scoped = 1; // namespace variables are like globals } // namespace foo // Lambdas should be ignored, because they do not follow the normal variable // semantic (e.g. the type is only known to the compiler). void lambdas() { auto Lambda = [](int i) { return i < 0; }; } void some_function(double, wchar_t); void some_function(double np_arg0, wchar_t np_arg1) { int p_local0 = 2; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'int' can be declared 'const' // CHECK-FIXES: int const p_local0 = 2; } void nested_scopes() { { int p_local1 = 42; // CHECK-MESSAGES: [[@LINE-1]]:5: warning: variable 'p_local1' of type 'int' can be declared 'const' // CHECK-FIXES: int const p_local1 = 42; } } template void define_locals(T np_arg0, T &np_arg1, int np_arg2) { T np_local0 = 0; int p_local1 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'int' can be declared 'const' // CHECK-FIXES: int const p_local1 = 42; } void template_instantiation() { const int np_local0 = 42; int np_local1 = 42; define_locals(np_local0, np_local1, np_local0); define_locals(np_local1, np_local1, np_local1); } struct ConstNonConstClass { ConstNonConstClass(); ConstNonConstClass(double &np_local0); double nonConstMethod() {} double constMethod() const {} double modifyingMethod(double &np_arg0) const; double NonConstMember; const double ConstMember; double &NonConstMemberRef; const double &ConstMemberRef; double *NonConstMemberPtr; const double *ConstMemberPtr; }; void direct_class_access() { ConstNonConstClass p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass' can be declared 'const' // CHECK-FIXES: ConstNonConstClass const p_local0; p_local0.constMethod(); } void class_access_array() { ConstNonConstClass p_local0[2]; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'ConstNonConstClass[2]' can be declared 'const' // CHECK-FIXES: ConstNonConstClass const p_local0[2]; p_local0[0].constMethod(); } struct MyVector { double *begin(); const double *begin() const; double *end(); const double *end() const; double &operator[](int index); double operator[](int index) const; double values[100]; }; void vector_usage() { double p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'double[10]' can be declared 'const' // CHECK-FIXES: double const p_local0[10] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 9.}; } void range_for() { int np_local0[2] = {1, 2}; // The transformation is not possible because the range-for-loop mutates the array content. int *const np_local1[2] = {&np_local0[0], &np_local0[1]}; for (int *non_const_ptr : np_local1) { *non_const_ptr = 45; } int *np_local2[2] = {&np_local0[0], &np_local0[1]}; for (int *non_const_ptr : np_local2) { *non_const_ptr = 45; } } void decltype_declaration() { decltype(sizeof(void *)) p_local0 = 42; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'decltype(sizeof(void *))' // CHECK-FIXES: decltype(sizeof(void *)) const p_local0 = 42; } // Taken from libcxx/include/type_traits and improved readability. template struct integral_constant { static constexpr const Tp value = v; using value_type = Tp; using type = integral_constant; constexpr operator value_type() const noexcept { return value; } constexpr value_type operator()() const noexcept { return value; } }; template struct is_integral : integral_constant {}; template <> struct is_integral : integral_constant {}; template struct not_integral : integral_constant {}; template <> struct not_integral : integral_constant {}; template struct enable_if {}; template struct enable_if { using type = Tp; }; template struct TMPClass { T alwaysConst() const { return T{}; } template ::value>::type> T sometimesConst() const { return T{}; } template ::value>::type> T sometimesConst() { return T{}; } }; void meta_type() { TMPClass p_local0; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local0' of type 'TMPClass' can be declared 'const' // CHECK-FIXES: TMPClass const p_local0; p_local0.alwaysConst(); p_local0.sometimesConst(); TMPClass p_local1; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p_local1' of type 'TMPClass' can be declared 'const' // CHECK-FIXES: TMPClass const p_local1; p_local1.alwaysConst(); TMPClass p_local2; // Don't attempt to make this const p_local2.sometimesConst(); }