1// RUN: %check_clang_tidy %s bugprone-return-const-ref-from-parameter %t -- -- -fno-delayed-template-parsing
2
3using T = int;
4using TConst = int const;
5using TConstRef = int const&;
6
7template <typename T>
8struct Wrapper { Wrapper(T); };
9
10template <typename T>
11struct Identity { using type = T; };
12
13template <typename T>
14struct ConstRef { using type = const T&; };
15
16namespace invalid {
17
18int const &f1(int const &a) { return a; }
19// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: returning a constant reference parameter
20
21int const &f2(T const &a) { return a; }
22// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: returning a constant reference parameter
23
24int const &f3(TConstRef a) { return a; }
25// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: returning a constant reference parameter
26
27int const &f4(TConst &a) { return a; }
28// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter
29
30int const &f5(TConst &a) { return true ? a : a; }
31// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: returning a constant reference parameter
32// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: returning a constant reference parameter
33
34template <typename T>
35const T& tf1(const T &a) { return a; }
36// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter
37
38template <typename T>
39const T& itf1(const T &a) { return a; }
40// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: returning a constant reference parameter
41
42template <typename T>
43typename ConstRef<T>::type itf2(const T &a) { return a; }
44// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter
45
46template <typename T>
47typename ConstRef<T>::type itf3(typename ConstRef<T>::type a) { return a; }
48// CHECK-MESSAGES: :[[@LINE-1]]:72: warning: returning a constant reference parameter
49
50template <typename T>
51const T& itf4(typename ConstRef<T>::type a) { return a; }
52// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter
53
54template <typename T>
55const T& itf5(const T &a) { return true ? a : a; }
56// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: returning a constant reference parameter
57// CHECK-MESSAGES: :[[@LINE-2]]:47: warning: returning a constant reference parameter
58
59void instantiate(const int &param, const float &paramf, int &mut_param, float &mut_paramf) {
60 itf1(a: 0);
61 itf1(a: param);
62 itf1(a: paramf);
63 itf2(a: 0);
64 itf2(a: param);
65 itf2(a: paramf);
66 itf3<int>(a: 0);
67 itf3<int>(a: param);
68 itf3<float>(a: paramf);
69 itf4<int>(a: 0);
70 itf4<int>(a: param);
71 itf4<float>(a: paramf);
72}
73
74struct C {
75 const C& foo(const C&c) { return c; }
76// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: returning a constant reference parameter
77};
78
79const auto Lf1 = [](const T& t) -> const T& { return t; };
80// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: returning a constant reference parameter
81
82} // namespace invalid
83
84namespace false_negative_because_dependent_and_not_instantiated {
85template <typename T>
86typename ConstRef<T>::type tf2(const T &a) { return a; }
87
88template <typename T>
89typename ConstRef<T>::type tf3(typename ConstRef<T>::type a) { return a; }
90
91template <typename T>
92const T& tf4(typename ConstRef<T>::type a) { return a; }
93} // false_negative_because_dependent_and_not_instantiated
94
95namespace valid {
96
97int const &f1(int &a) { return a; }
98
99int const &f2(int &&a) { return a; }
100
101int f1(int const &a) { return a; }
102
103template <typename T>
104T tf1(T a) { return a; }
105
106template <typename T>
107T tf2(const T a) { return a; }
108
109template <typename T>
110T tf3(const T &a) { return a; }
111
112template <typename T>
113Identity<T>::type tf4(const T &a) { return a; }
114
115template <typename T>
116T itf1(T a) { return a; }
117
118template <typename T>
119T itf2(const T a) { return a; }
120
121template <typename T>
122T itf3(const T &a) { return a; }
123
124template <typename T>
125Wrapper<T> itf4(const T& a) { return a; }
126
127template <typename T>
128const T& itf5(T& a) { return a; }
129
130template <typename T>
131T itf6(T& a) { return a; }
132
133void instantiate(const int &param, const float &paramf, int &mut_param, float &mut_paramf) {
134 itf1(a: 0);
135 itf1(a: param);
136 itf1(a: paramf);
137 itf2(a: 0);
138 itf2(a: param);
139 itf2(a: paramf);
140 itf3(a: 0);
141 itf3(a: param);
142 itf3(a: paramf);
143 itf2(a: 0);
144 itf2(a: param);
145 itf2(a: paramf);
146 itf3(a: 0);
147 itf3(a: param);
148 itf3(a: paramf);
149 itf4(a: param);
150 itf4(a: paramf);
151 itf5(a&: mut_param);
152 itf5(a&: mut_paramf);
153 itf6(a&: mut_param);
154 itf6(a&: mut_paramf);
155}
156
157template<class T>
158void f(const T& t) {
159 const auto get = [&t] -> const T& { return t; };
160 return T{};
161}
162
163const auto Lf1 = [](T& t) -> const T& { return t; };
164
165} // namespace valid
166
167namespace overload {
168
169int const &overload_base(int const &a) { return a; }
170int const &overload_base(int &&a);
171
172int const &overload_ret_type(int const &a) { return a; }
173void overload_ret_type(int &&a);
174
175int const &overload_params1(int p1, int const &a) { return a; }
176int const & overload_params1(int p1, int &&a);
177
178int const &overload_params2(int p1, int const &a, int p2) { return a; }
179int const &overload_params2(int p1, int &&a, int p2);
180
181int const &overload_params3(T p1, int const &a, int p2) { return a; }
182int const &overload_params3(int p1, int &&a, T p2);
183
184int const &overload_params_const(int p1, int const &a, int const p2) { return a; }
185int const &overload_params_const(int const p1, int &&a, int p2);
186
187int const &overload_params_difference1(int p1, int const &a, int p2) { return a; }
188// CHECK-MESSAGES: :[[@LINE-1]]:79: warning: returning a constant reference parameter
189int const &overload_params_difference1(long p1, int &&a, int p2);
190
191int const &overload_params_difference2(int p1, int const &a, int p2) { return a; }
192// CHECK-MESSAGES: :[[@LINE-1]]:79: warning: returning a constant reference parameter
193int const &overload_params_difference2(int p1, int &&a, long p2);
194
195int const &overload_params_difference3(int p1, int const &a, int p2) { return a; }
196// CHECK-MESSAGES: :[[@LINE-1]]:79: warning: returning a constant reference parameter
197int const &overload_params_difference3(int p1, long &&a, int p2);
198
199} // namespace overload
200
201namespace gh117696 {
202namespace use_lifetime_bound_attr {
203int const &f(int const &a [[clang::lifetimebound]]) { return a; }
204} // namespace use_lifetime_bound_attr
205} // namespace gh117696
206
207
208namespace lambda {
209using T = const int &;
210using K = const float &;
211T inner_valid_lambda(T a) {
212 [&]() -> T { return a; };
213 return a;
214 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: returning a constant reference parameter
215}
216T inner_invalid_lambda(T a) {
217 [&](T a) -> T { return a; };
218 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: returning a constant reference parameter
219 return a;
220 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: returning a constant reference parameter
221}
222T inner_invalid_lambda2(T a) {
223 [&](K a) -> K { return a; };
224 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: returning a constant reference parameter
225 return a;
226 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: returning a constant reference parameter
227}
228} // namespace lambda
229

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp