1 // RUN: %check_clang_tidy -std=c++14-or-later %s modernize-use-trailing-return-type %t -- -- -fdeclspec -fexceptions -DCOMMAND_LINE_INT=int
2 
3 namespace std {
4     template <typename T>
5     class vector;
6 
7     template <typename T, int N>
8     class array;
9 
10     class string;
11 
12     template <typename T>
13     class basic_ostream;
14 
15     using ostream = basic_ostream<char>;
16 
17     template <typename T>
18     auto declval() -> T;
19 
20     template <typename... Ts>
21     class tuple;
22 }
23 
24 //
25 // Functions
26 //
27 
28 int f();
29 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
30 // CHECK-FIXES: {{^}}auto f() -> int;{{$}}
31 int ((f))();
32 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
33 // CHECK-FIXES: {{^}}auto ((f))() -> int;{{$}}
34 int f(int);
35 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
36 // CHECK-FIXES: {{^}}auto f(int) -> int;{{$}}
37 int f(int arg);
38 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
39 // CHECK-FIXES: {{^}}auto f(int arg) -> int;{{$}}
40 int f(int arg1, int arg2, int arg3);
41 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
42 // CHECK-FIXES: {{^}}auto f(int arg1, int arg2, int arg3) -> int;{{$}}
43 int f(int arg1, int arg2, int arg3, ...);
44 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
45 // CHECK-FIXES: {{^}}auto f(int arg1, int arg2, int arg3, ...) -> int;{{$}}
46 template <typename T> int f(T t);
47 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
48 // CHECK-FIXES: {{^}}template <typename T> auto f(T t) -> int;{{$}}
49 
50 //
51 // Functions with formatting
52 //
53 
a1()54 int a1() { return 42; }
55 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
56 // CHECK-FIXES: {{^}}auto a1() -> int { return 42; }{{$}}
a2()57 int a2() {
58     return 42;
59 }
60 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
61 // CHECK-FIXES: {{^}}auto a2() -> int {{{$}}
a3()62 int a3()
63 {
64     return 42;
65 }
66 // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
67 // CHECK-FIXES: {{^}}auto a3() -> int{{$}}
68 int a4(int   arg   )   ;
69 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
70 // CHECK-FIXES: {{^}}auto a4(int   arg   ) -> int   ;{{$}}
71 int a5
72 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
73 // CHECK-FIXES: {{^}}auto a5{{$}}
74 (int arg);
75 // CHECK-FIXES: {{^}}(int arg) -> int;{{$}}
76 const
77 int
78 *
79 a7
80 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
81 ()
82 // CHECK-FIXES: {{^}}() -> const{{$}}
83 // CHECK-FIXES: {{^}}int{{$}}
84 // CHECK-FIXES: {{^}}*{{$}}
85 ;
86 
87 int*a7(int arg);
88 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
89 // CHECK-FIXES: {{^}}auto a7(int arg) -> int*;{{$}}
90 template<template <typename> class C>
91 C<int>a8(int arg);
92 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
93 // CHECK-FIXES: {{^}}auto a8(int arg) -> C<int>;{{$}}
94 
95 
96 //
97 // Functions with qualifiers and specifiers
98 //
99 
100 inline int d1(int arg);
101 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
102 // CHECK-FIXES: {{^}}inline auto d1(int arg) -> int;{{$}}
103 extern "C" int d2(int arg);
104 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
105 // CHECK-FIXES: {{^}}extern "C" auto d2(int arg) -> int;{{$}}
106 inline int d3(int arg) noexcept(true);
107 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
108 // CHECK-FIXES: {{^}}inline auto d3(int arg) noexcept(true) -> int;{{$}}
d4(int arg)109 inline int d4(int arg) try { } catch(...) { }
110 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
111 // CHECK-FIXES: {{^}}inline auto d4(int arg) -> int try { } catch(...) { }{{$}}
112 int d5(int arg) throw();
113 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
114 // CHECK-FIXES: {{^}}auto d5(int arg) throw() -> int;{{$}}
115 static int d6(int arg);
116 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
117 // CHECK-FIXES: {{^}}static auto d6(int arg) -> int;{{$}}
118 int static d6(int arg);
119 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
120 // CHECK-FIXES: {{^}}auto static d6(int arg) -> int;{{$}}
121 unsigned static int d7(int arg);
122 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
123 // CHECK-FIXES: {{^}}static auto d7(int arg) -> unsigned int;{{$}}
124 const long static int volatile constexpr unsigned inline long d8(int arg);
125 // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
126 // CHECK-FIXES: {{^}}static constexpr inline auto d8(int arg) -> const long int volatile unsigned long;{{$}}
127 int constexpr d9();
128 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
129 // CHECK-FIXES: {{^}}auto constexpr d9() -> int;{{$}}
130 inline int constexpr d10();
131 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
132 // CHECK-FIXES: {{^}}inline auto constexpr d10() -> int;{{$}}
133 unsigned constexpr int d11();
134 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
135 // CHECK-FIXES: {{^}}constexpr auto d11() -> unsigned int;{{$}}
136 unsigned extern int d13();
137 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
138 // CHECK-FIXES: {{^}}extern auto d13() -> unsigned int;{{$}}
139 int static& d14();
140 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
141 // CHECK-FIXES: {{^}}static auto d14() -> int &;{{$}}
142 class DDD {
143     int friend unsigned m1();
144 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
145 // CHECK-FIXES: {{^}}    friend auto m1() -> int unsigned;{{$}}
m1()146     int friend unsigned m1() { return 0; }
147 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
148 // CHECK-FIXES: {{^}}    friend auto m1() -> int unsigned { return 0; }{{$}}
149     const long int friend volatile constexpr unsigned inline long m2();
150 // CHECK-MESSAGES: :[[@LINE-1]]:67: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
151 // CHECK-FIXES: {{^}}    friend constexpr inline auto m2() -> const long int volatile unsigned long;{{$}}
152     int virtual unsigned m3();
153 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
154 // CHECK-FIXES: {{^}}    virtual auto m3() -> int unsigned;{{$}}
155     template <typename T>
156     int friend unsigned m4();
157 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
158 // CHECK-FIXES: {{^}}    friend auto m4() -> int unsigned;{{$}}
159 };
160 
161 //
162 // Functions in namespaces
163 //
164 
165 namespace N {
166     int e1();
167 }
168 // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
169 // CHECK-FIXES: {{^}}    auto e1() -> int;{{$}}
e1()170 int N::e1() {}
171 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
172 // CHECK-FIXES: {{^}}auto N::e1() -> int {}{{$}}
173 
174 //
175 // Functions with unsupported return types
176 //
177 int (*e3())(double);
178 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
179 // CHECK-FIXES: {{^}}int (*e3())(double);{{$}}
180 struct A;
181 int A::* e5();
182 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
183 // CHECK-FIXES: {{^}}int A::* e5();{{$}}
184 int std::vector<std::string>::* e6();
185 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
186 // CHECK-FIXES: {{^}}int std::vector<std::string>::* e6();{{$}}
187 int (std::vector<std::string>::*e7())(double);
188 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
189 // CHECK-FIXES: {{^}}int (std::vector<std::string>::*e7())(double);{{$}}
190 
191 //
192 // Functions with complex return types
193 //
194 
195 inline volatile const std::vector<std::string> e2();
196 // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
197 // CHECK-FIXES: {{^}}inline auto e2() -> volatile const std::vector<std::string>;{{$}}
198 inline const std::vector<std::string> volatile e2();
199 // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
200 // CHECK-FIXES: {{^}}inline auto e2() -> const std::vector<std::string> volatile;{{$}}
201 inline std::vector<std::string> const volatile e2();
202 // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
203 // CHECK-FIXES: {{^}}inline auto e2() -> std::vector<std::string> const volatile;{{$}}
204 int* e8();
205 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
206 // CHECK-FIXES: {{^}}auto e8() -> int*;{{$}}
207 static const char* e9(void* user_data);
208 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
209 // CHECK-FIXES: {{^}}static auto e9(void* user_data) -> const char*;{{$}}
210 static const char* const e10(void* user_data);
211 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
212 // CHECK-FIXES: {{^}}static auto e10(void* user_data) -> const char* const;{{$}}
213 static const char** volatile * const & e11(void* user_data);
214 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
215 // CHECK-FIXES: {{^}}static auto e11(void* user_data) -> const char** volatile * const &;{{$}}
216 static const char* const * const * const e12(void* user_data);
217 // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
218 // CHECK-FIXES: {{^}}static auto e12(void* user_data) -> const char* const * const * const;{{$}}
219 struct A e13();
220 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
221 // CHECK-FIXES: {{^}}auto e13() -> struct A;{{$}}
222 
223 //
224 // deduced return types
225 //
226 
227 const auto ded1();
228 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
229 // CHECK-FIXES: {{^}}auto ded1() -> const auto;{{$}}
230 const auto& ded2();
231 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
232 // CHECK-FIXES: {{^}}auto ded2() -> const auto&;{{$}}
233 
234 decltype(auto) ded3();
235 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
236 // CHECK-FIXES: {{^}}auto ded3() -> decltype(auto);{{$}}
237 
238 
dec1()239 decltype(1 + 2) dec1() { return 1 + 2; }
240 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
241 // CHECK-FIXES: {{^}}auto dec1() -> decltype(1 + 2) { return 1 + 2; }{{$}}
242 template <typename F, typename T>
dec2(F f,T t)243 decltype(std::declval<F>(std::declval<T>)) dec2(F f, T t) { return f(t); }
244 // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
245 // CHECK-FIXES: {{^}}auto dec2(F f, T t) -> decltype(std::declval<F>(std::declval<T>)) { return f(t); }{{$}}
246 template <typename T>
247 typename decltype(std::declval<T>())::value_type dec3();
248 // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
249 // CHECK-FIXES: {{^}}auto dec3() -> typename decltype(std::declval<T>())::value_type;{{$}}
250 template <typename T>
251 decltype(std::declval<T>())* dec4();
252 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
253 // CHECK-FIXES: {{^}}auto dec4() -> decltype(std::declval<T>())*;{{$}}
254 
255 //
256 // Methods
257 //
258 
259 struct B {
260     B& operator=(const B&);
261 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
262 // CHECK-FIXES: {{^}}    auto operator=(const B&) -> B&;{{$}}
263 
264     double base1(int, bool b);
265 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
266 // CHECK-FIXES: {{^}}    auto base1(int, bool b) -> double;{{$}}
267 
base2B268     virtual double base2(int, bool b) {}
269 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
270 // CHECK-FIXES: {{^}}    virtual auto base2(int, bool b) -> double {}{{$}}
271 
272     virtual float base3() const = 0;
273 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
274 // CHECK-FIXES: {{^}}    virtual auto base3() const -> float = 0;{{$}}
275 
276     virtual float base4() volatile = 0;
277 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
278 // CHECK-FIXES: {{^}}    virtual auto base4() volatile -> float = 0;{{$}}
279 
280     double base5(int, bool b) &&;
281 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
282 // CHECK-FIXES: {{^}}    auto base5(int, bool b) && -> double;{{$}}
283 
284     double base6(int, bool b) const &&;
285 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
286 // CHECK-FIXES: {{^}}    auto base6(int, bool b) const && -> double;{{$}}
287 
288     double base7(int, bool b) const & = delete;
289 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
290 // CHECK-FIXES: {{^}}    auto base7(int, bool b) const & -> double = delete;{{$}}
291 
292     double base8(int, bool b) const volatile & = delete;
293 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
294 // CHECK-FIXES: {{^}}    auto base8(int, bool b) const volatile & -> double = delete;{{$}}
295 
base9B296     virtual const char * base9() const noexcept { return ""; }
297 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
298 // CHECK-FIXES: {{^}}    virtual auto base9() const noexcept -> const char * { return ""; }{{$}}
299 };
300 
base1(int,bool b)301 double B::base1(int, bool b) {}
302 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
303 // CHECK-FIXES: {{^}}auto B::base1(int, bool b) -> double {}{{$}}
304 
305 struct D : B {
306     virtual double f1(int, bool b) final;
307 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
308 // CHECK-FIXES: {{^}}    virtual auto f1(int, bool b) -> double final;{{$}}
309 
310     virtual double base2(int, bool b) override;
311 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
312 // CHECK-FIXES: {{^}}    virtual auto base2(int, bool b) -> double override;{{$}}
313 
base3D314     virtual float base3() const override final { }
315 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
316 // CHECK-FIXES: {{^}}    virtual auto base3() const -> float override final { }{{$}}
317 
base9D318     const char * base9() const noexcept override { return ""; }
319 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
320 // CHECK-FIXES: {{^}}    auto base9() const noexcept -> const char * override { return ""; }{{$}}
321 
322     int f2() __restrict;
323 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
324 // CHECK-FIXES: {{^}}    auto f2() __restrict -> int;{{$}}
325 
326     volatile int* __restrict f3() const __restrict noexcept;
327 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
328 // CHECK-FIXES: {{^}}    auto f3() const __restrict noexcept -> volatile int* __restrict;{{$}}
329 };
330 
331 //
332 // Functions with attributes
333 //
334 
335 int g1() [[asdf]];
336 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
337 // CHECK-FIXES: {{^}}auto g1() -> int {{[[][[]}}asdf{{[]][]]}};{{$}}
338 [[noreturn]] int g2();
339 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
340 // CHECK-FIXES: {{^}}{{[[][[]}}noreturn{{[]][]]}} auto g2() -> int;{{$}}
341 int g2 [[noreturn]] ();
342 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
343 // CHECK-FIXES: {{^}}auto g2 {{[[][[]}}noreturn{{[]][]]}} () -> int;{{$}}
344 int unsigned g3() __attribute__((cdecl)); // FunctionTypeLoc is null.
345 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
346 int unsigned __attribute__((cdecl)) g3() ; // FunctionTypeLoc is null.
347 // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
348 __attribute__((cdecl)) int unsigned g3() ; // FunctionTypeLoc is null.
349 // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
350 
351 //
352 // Templates
353 //
354 template <typename Container>
355 [[maybe_unused]] typename Container::value_type const volatile&& t1(Container& C) noexcept;
356 // CHECK-MESSAGES: :[[@LINE-1]]:66: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
357 // CHECK-FIXES: {{^}}{{[[][[]}}maybe_unused{{[]][]]}} auto t1(Container& C) noexcept -> typename Container::value_type const volatile&&;{{$}}
358 template <typename T>
359 class BB {
360     using type = int;
361 
362     template <typename U>
363     typename BB<U>::type m1();
364 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
365 // CHECK-FIXES: {{^}}    auto m1() -> typename BB<U>::type;{{$}}
366 };
367 
368 //
369 // Macros
370 //
371 
372 #define DWORD unsigned int
373 DWORD h1();
374 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
375 // CHECK-FIXES: {{^}}auto h1() -> DWORD;{{$}}
376 #define INT int
377 #define UNSIGNED unsigned
378 UNSIGNED INT h2();
379 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
380 // CHECK-FIXES: {{^}}auto h2() -> UNSIGNED INT;{{$}}
381 #define CONST const
382 CONST int h3();
383 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
384 // CHECK-FIXES: {{^}}auto h3() -> CONST int;{{$}}
385 #define ALWAYS_INLINE inline
386 #define DLL_EXPORT __declspec(dllexport)
387 ALWAYS_INLINE DLL_EXPORT int h4();
388 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
389 // CHECK-FIXES: {{^}}ALWAYS_INLINE DLL_EXPORT auto h4() -> int;{{$}}
390 #define DEPRECATED __attribute__((deprecated))
391 int h5() DEPRECATED;
392 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
393 // CHECK-FIXES: {{^}}auto h5() -> int DEPRECATED;{{$}}
394 int DEPRECATED h5();
395 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
396 // CHECK-FIXES: {{^}}auto DEPRECATED h5() -> int;{{$}}
397 DEPRECATED int h5();
398 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
399 // CHECK-FIXES: {{^}}DEPRECATED auto h5() -> int;{{$}}
400 [[noreturn]] [[nodiscard]] DEPRECATED DLL_EXPORT int h6 [[deprecated]] ();
401 // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
402 // CHECK-FIXES: {{^}}{{[[][[]}}noreturn{{[]][]]}} {{[[][[]}}nodiscard{{[]][]]}} DEPRECATED DLL_EXPORT auto h6 {{[[][[]}}deprecated{{[]][]]}} () -> int;{{$}}
403 #define FUNCTION_NAME(a, b) a##b
404 int FUNCTION_NAME(foo, bar)();
405 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
406 // CHECK-FIXES: {{^}}auto FUNCTION_NAME(foo, bar)() -> int;{{$}}
407 #define DEFINE_FUNCTION_1(a, b) int a##b()
408 DEFINE_FUNCTION_1(foo, bar);
409 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
410 #define DEFINE_FUNCTION_2 int foo(int arg);
411 DEFINE_FUNCTION_2
412 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
413 #define DLL_EXPORT_const __declspec(dllexport) const
414 DLL_EXPORT_const int h7();
415 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
416 #define DLL_EXPORT_CONST __declspec(dllexport) CONST
417 DLL_EXPORT_CONST int h7();
418 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
419 
420 template <typename T>
421 using Real = T;
422 #define PRECISION float
h8()423 Real<PRECISION> h8() { return 0.; }
424 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
425 // CHECK-FIXES: {{^}}auto h8() -> Real<PRECISION> { return 0.; }{{$}}
426 
427 #define MAYBE_UNUSED_MACRO [[maybe_unused]]
428 template <typename Container>
429 MAYBE_UNUSED_MACRO typename Container::value_type const volatile** const h9(Container& C) noexcept;
430 // CHECK-MESSAGES: :[[@LINE-1]]:74: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
431 // CHECK-FIXES: {{^}}MAYBE_UNUSED_MACRO auto h9(Container& C) noexcept -> typename Container::value_type const volatile** const;{{$}}
432 
433 #define NOEXCEPT noexcept
434 int h9(int arg) NOEXCEPT;
435 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
436 // CHECK-FIXES: {{^}}auto h9(int arg) NOEXCEPT -> int;{{$}}
437 #define STATIC_INT static int
438 STATIC_INT h10();
439 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
440 #define UNSIGNED_STATIC_INT unsigned static int
441 UNSIGNED_STATIC_INT h11();
442 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
443 #define STATIC static
444 unsigned STATIC int h11();
445 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
446 // CHECK-FIXES: {{^}}STATIC auto h11() -> unsigned int;{{$}}
447 #define STATIC_CONSTEXPR static constexpr
448 unsigned STATIC_CONSTEXPR int h12();
449 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
450 // CHECK-FIXES: {{^}}STATIC_CONSTEXPR auto h12() -> unsigned int;{{$}}
451 #define STATIC_CONSTEXPR_LONG static constexpr long
452 unsigned STATIC_CONSTEXPR_LONG int h13();
453 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
454 DEPRECATED const int& h14();
455 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
456 // CHECK-FIXES: {{^}}DEPRECATED auto h14() -> const int&;{{$}}
457 DEPRECATED const long static volatile unsigned& h15();
458 // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
459 // CHECK-FIXES: {{^}}DEPRECATED static auto h15() -> const long volatile unsigned&;{{$}}
460 #define WRAP(x) x
461 WRAP(const) int& h16();
462 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
463 WRAP(CONST) int& h16();
464 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
465 #define CONCAT(a, b) a##b
466 CONCAT(con, st) int& h16();
467 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
468 DEPRECATED const UNSIGNED& h17();
469 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
470 // CHECK-FIXES: {{^}}DEPRECATED auto h17() -> const UNSIGNED&;{{$}}
471 DEPRECATED CONST UNSIGNED STATIC& h18();
472 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
473 // CHECK-FIXES: {{^}}DEPRECATED STATIC auto h18() -> CONST UNSIGNED &;{{$}}
474 #define CONST_CAT con##st
475 CONST_CAT int& h19();
476 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
477 // CHECK-FIXES: {{^}}auto h19() -> CONST_CAT int&;{{$}}
478 #define CONST_F_MACRO WRAP(CONST_CAT)
479 CONST_F_MACRO int& h19();
480 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
481 // CHECK-FIXES: {{^}}auto h19() -> CONST_F_MACRO int&;{{$}}
482 // Macro COMMAND_LINE_INT is defined on the command line via: -DCOMMAND_LINE_INT=int
483 const COMMAND_LINE_INT& h20();
484 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
485 // CHECK-FIXES: {{^}}auto h20() -> const COMMAND_LINE_INT&;{{$}}
486 decltype(COMMAND_LINE_INT{}) h21();
487 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
488 // CHECK-FIXES: {{^}}auto h21() -> decltype(COMMAND_LINE_INT{});{{$}}
489 
490 //
491 // Name collisions
492 //
493 struct Object { long long value; };
494 
j1(unsigned Object)495 Object j1(unsigned Object) { return {Object * 2}; }
496 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
497 // CHECK-FIXES: {{^}}Object j1(unsigned Object) { return {Object * 2}; }{{$}}
498 ::Object j1(unsigned Object);
499 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
500 // CHECK-FIXES: {{^}}auto j1(unsigned Object) -> ::Object;{{$}}
501 const Object& j2(unsigned a, int b, char Object, long l);
502 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
503 // CHECK-FIXES: {{^}}const Object& j2(unsigned a, int b, char Object, long l);{{$}}
504 const struct Object& j2(unsigned a, int b, char Object, long l);
505 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
506 // CHECK-FIXES: {{^}}auto j2(unsigned a, int b, char Object, long l) -> const struct Object&;{{$}}
507 std::vector<Object> j3(unsigned Object);
508 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
509 // CHECK-FIXES: {{^}}std::vector<Object> j3(unsigned Object);{{$}}
510 std::vector<const Object> j7(unsigned Object);
511 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
512 // CHECK-FIXES: {{^}}std::vector<const Object> j7(unsigned Object);{{$}}
513 std::vector<Object> j4(unsigned vector);
514 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
515 // CHECK-FIXES: {{^}}auto j4(unsigned vector) -> std::vector<Object>;{{$}}
516 std::vector<::Object> j4(unsigned vector);
517 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
518 // CHECK-FIXES: {{^}}auto j4(unsigned vector) -> std::vector<::Object>;{{$}}
519 std::vector<struct Object> j4(unsigned vector);
520 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
521 // CHECK-FIXES: {{^}}auto j4(unsigned vector) -> std::vector<struct Object>;{{$}}
522 std::vector<Object> j4(unsigned Vector);
523 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
524 // CHECK-FIXES: {{^}}auto j4(unsigned Vector) -> std::vector<Object>;{{$}}
525 using std::vector;
526 vector<Object> j5(unsigned vector);
527 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
528 // CHECK-FIXES: {{^}}vector<Object> j5(unsigned vector);{{$}}
529 constexpr auto Size = 5;
530 std::array<int, Size> j6(unsigned Size);
531 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
532 // CHECK-FIXES: {{^}}std::array<int, Size> j6(unsigned Size);{{$}}
533 std::array<decltype(Size), (Size * 2) + 1> j8(unsigned Size);
534 // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
535 // CHECK-FIXES: {{^}}std::array<decltype(Size), (Size * 2) + 1> j8(unsigned Size);{{$}}
536 using std::ostream;
537 std::tuple<int, std::string, ostream>& operator<<(ostream& ostream, float i);
538 // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
539 // CHECK-FIXES: {{^}}std::tuple<int, std::string, ostream>& operator<<(ostream& ostream, float i);{{$}}
540 
541 class CC {
542     int Object;
543     struct Object m();
544 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
545 // CHECK-FIXES: {{^}}    auto m() -> struct Object;{{$}}
546 };
m()547 Object CC::m() { return {0}; }
548 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
549 // CHECK-FIXES: {{^}}auto CC::m() -> Object { return {0}; }{{$}}
550 class DD : public CC {
551     ::Object g();
552 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
553 // CHECK-FIXES: {{^}}    auto g() -> ::Object;{{$}}
554 };
g()555 Object DD::g() {
556 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
557 // CHECK-FIXES: {{^}}auto DD::g() -> Object {{{$}}
558     return {0};
559 }
560 
561 //
562 // bug 44206, no rewrite should happen due to collision with parameter name
563 //
564 
565 ostream& operator<<(ostream& ostream, int i);
566 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
567 // CHECK-FIXES: {{^}}ostream& operator<<(ostream& ostream, int i);{{$}}
568 
569 //
570 // Samples which do not trigger the check
571 //
572 
573 auto f() -> int;
574 auto f(int) -> int;
575 auto f(int arg) -> int;
576 auto f(int arg1, int arg2, int arg3) -> int;
577 auto f(int arg1, int arg2, int arg3, ...) -> int;
578 template <typename T> auto f(T t) -> int;
579 
580 auto ff();
581 
582 void c();
583 void c(int arg);
c(int arg)584 void c(int arg) { return; }
585 
586 struct D2 : B {
587     D2();
588     virtual ~D2();
589 
590     virtual auto f1(int, bool b) -> double final;
591     virtual auto base2(int, bool b) -> double override;
base3D2592     virtual auto base3() const -> float override final { }
593 
594     operator double();
595 };
596 
__anon34d54cdc0102(int arg) 597 auto l1 = [](int arg) {};
__anon34d54cdc0202(int arg) 598 auto l2 = [](int arg) -> double {};
599