146ae26e7SJonas Toth // RUN: %check_clang_tidy %s misc-const-correctness %t -- \ 21af159e9SPiotr Zegar // RUN: -config="{CheckOptions: {\ 31af159e9SPiotr Zegar // RUN: misc-const-correctness.TransformValues: true, \ 41af159e9SPiotr Zegar // RUN: misc-const-correctness.TransformReferences: true, \ 51af159e9SPiotr Zegar // RUN: misc-const-correctness.WarnPointersAsValues: false, \ 61af159e9SPiotr Zegar // RUN: misc-const-correctness.TransformPointersAsValues: false} \ 71af159e9SPiotr Zegar // RUN: }" -- -fno-delayed-template-parsing 846ae26e7SJonas Toth 946ae26e7SJonas Toth template <typename T> type_dependent_variables()1046ae26e7SJonas Tothvoid type_dependent_variables() { 1146ae26e7SJonas Toth T value = 42; 1246ae26e7SJonas Toth auto &ref = value; 1346ae26e7SJonas Toth T &templateRef = value; 1446ae26e7SJonas Toth 1546ae26e7SJonas Toth int value_int = 42; 1646ae26e7SJonas Toth // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'value_int' of type 'int' can be declared 'const' 1746ae26e7SJonas Toth // CHECK-FIXES: int const value_int 1846ae26e7SJonas Toth } instantiate_template_cases()1946ae26e7SJonas Tothvoid instantiate_template_cases() { 2046ae26e7SJonas Toth type_dependent_variables<int>(); 2146ae26e7SJonas Toth type_dependent_variables<float>(); 2246ae26e7SJonas Toth } 23a3d76b3fSJulian Schmidt 24a3d76b3fSJulian Schmidt namespace gh57297{ 25a3d76b3fSJulian Schmidt // The expression to check may not be the dependent operand in a dependent 26a3d76b3fSJulian Schmidt // operator. 27a3d76b3fSJulian Schmidt 28a3d76b3fSJulian Schmidt // Explicitly not declaring a (templated) stream operator 29a3d76b3fSJulian Schmidt // so the `<<` is a `binaryOperator` with a dependent type. 30a3d76b3fSJulian Schmidt struct Stream { }; f()31a3d76b3fSJulian Schmidttemplate <typename T> void f() { T t; Stream x; x << t; } 32a3d76b3fSJulian Schmidt } // namespace gh57297 339f8ccf50SJulian Schmidt 349f8ccf50SJulian Schmidt namespace gh70323{ 359f8ccf50SJulian Schmidt // A fold expression may contain the checked variable as it's initializer. 369f8ccf50SJulian Schmidt // We don't know if the operator modifies that variable because the 379f8ccf50SJulian Schmidt // operator is type dependent due to the parameter pack. 389f8ccf50SJulian Schmidt 399f8ccf50SJulian Schmidt struct Stream {}; 409f8ccf50SJulian Schmidt template <typename... Args> concatenate1(Args...args)419f8ccf50SJulian Schmidtvoid concatenate1(Args... args) 429f8ccf50SJulian Schmidt { 439f8ccf50SJulian Schmidt Stream stream; 449f8ccf50SJulian Schmidt (stream << ... << args); 459f8ccf50SJulian Schmidt } 469f8ccf50SJulian Schmidt 479f8ccf50SJulian Schmidt template <typename... Args> concatenate2(Args...args)489f8ccf50SJulian Schmidtvoid concatenate2(Args... args) 499f8ccf50SJulian Schmidt { 509f8ccf50SJulian Schmidt Stream stream; 519f8ccf50SJulian Schmidt (args << ... << stream); 529f8ccf50SJulian Schmidt } 539f8ccf50SJulian Schmidt 549f8ccf50SJulian Schmidt template <typename... Args> concatenate3(Args...args)559f8ccf50SJulian Schmidtvoid concatenate3(Args... args) 569f8ccf50SJulian Schmidt { 579f8ccf50SJulian Schmidt Stream stream; 589f8ccf50SJulian Schmidt (..., (stream << args)); 599f8ccf50SJulian Schmidt } 609f8ccf50SJulian Schmidt } // namespace gh70323 61*f40f4fceSCongcong Cai 62*f40f4fceSCongcong Cai namespace gh60895 { 63*f40f4fceSCongcong Cai 64*f40f4fceSCongcong Cai template <class T> void f1(T &&a); 65*f40f4fceSCongcong Cai template <class T> void f2(T &&a); f1(T && a)66*f40f4fceSCongcong Caitemplate <class T> void f1(T &&a) { f2<T>(a); } f2(T && a)67*f40f4fceSCongcong Caitemplate <class T> void f2(T &&a) { f1<T>(a); } f()68*f40f4fceSCongcong Caivoid f() { 69*f40f4fceSCongcong Cai int x = 0; 70*f40f4fceSCongcong Cai // CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'x' of type 'int' can be declared 'const' 71*f40f4fceSCongcong Cai // CHECK-FIXES: int const x = 0; 72*f40f4fceSCongcong Cai f1(x); 73*f40f4fceSCongcong Cai } 74*f40f4fceSCongcong Cai 75*f40f4fceSCongcong Cai } // namespace gh60895 76