xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-templates.cpp (revision f40f4fcee506deacda0594362509ee7dddcf5e37)
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 Toth void 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 Toth void 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 Schmidt template <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 Schmidt void 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 Schmidt void 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 Schmidt void 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 Cai template <class T> void f1(T &&a) { f2<T>(a); }
f2(T && a)67*f40f4fceSCongcong Cai template <class T> void f2(T &&a) { f1<T>(a); }
f()68*f40f4fceSCongcong Cai void 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