blob: 15b3e274707289046c86524a1f86e91c4090cc2c [file] [log] [blame]
// RUN: %check_clang_tidy -std=c++14,c++17 %s modernize-use-trailing-return-type %t -- -- -fdeclspec -fexceptions
// FIXME: Fix the checker to work in C++2a mode, it is performing a
// use-of-uninitialized-value.
namespace std {
template <typename T>
class vector;
template <typename T, int N>
class array;
class string;
template <typename T>
auto declval() -> T;
}
//
// Functions
//
int f();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto f() -> int;{{$}}
int ((f))();
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto ((f))() -> int;{{$}}
int f(int);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto f(int) -> int;{{$}}
int f(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto f(int arg) -> int;{{$}}
int f(int arg1, int arg2, int arg3);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto f(int arg1, int arg2, int arg3) -> int;{{$}}
int f(int arg1, int arg2, int arg3, ...);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto f(int arg1, int arg2, int arg3, ...) -> int;{{$}}
template <typename T> int f(T t);
// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}template <typename T> auto f(T t) -> int;{{$}}
//
// Functions with formatting
//
int a1() { return 42; }
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a1() -> int { return 42; }{{$}}
int a2() {
return 42;
}
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a2() -> int {{{$}}
int a3()
{
return 42;
}
// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a3() -> int{{$}}
int a4(int arg ) ;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a4(int arg ) -> int ;{{$}}
int a5
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a5{{$}}
(int arg);
// CHECK-FIXES: {{^}}(int arg) -> int;{{$}}
const
int
*
a7
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
()
// CHECK-FIXES: {{^}}() -> const{{$}}
// CHECK-FIXES: {{^}}int{{$}}
// CHECK-FIXES: {{^}}*{{$}}
;
int*a7(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a7(int arg) -> int*;{{$}}
template<template <typename> class C>
C<int>a8(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto a8(int arg) -> C<int>;{{$}}
//
// Functions with qualifiers and specifiers
//
inline int d1(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto d1(int arg) -> int;{{$}}
extern "C" int d2(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}extern "C" auto d2(int arg) -> int;{{$}}
inline int d3(int arg) noexcept(true);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto d3(int arg) noexcept(true) -> int;{{$}}
inline int d4(int arg) try { } catch(...) { }
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto d4(int arg) -> int try { } catch(...) { }{{$}}
int d5(int arg) throw();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto d5(int arg) throw() -> int;{{$}}
static int d6(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto d6(int arg) -> int;{{$}}
int static d6(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto static d6(int arg) -> int;{{$}}
unsigned static int d7(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto d7(int arg) -> unsigned int;{{$}}
const long static int volatile constexpr unsigned inline long d8(int arg);
// CHECK-MESSAGES: :[[@LINE-1]]:63: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static constexpr inline auto d8(int arg) -> const long int volatile unsigned long;{{$}}
int constexpr d9();
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto constexpr d9() -> int;{{$}}
inline int constexpr d10();
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto constexpr d10() -> int;{{$}}
unsigned constexpr int d11();
// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}constexpr auto d11() -> unsigned int;{{$}}
unsigned extern int d13();
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}extern auto d13() -> unsigned int;{{$}}
int static& d14();
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto d14() -> int &;{{$}}
class DDD {
int friend unsigned m1();
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} friend auto m1() -> int unsigned;{{$}}
int friend unsigned m1() { return 0; }
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} friend auto m1() -> int unsigned { return 0; }{{$}}
const long int friend volatile constexpr unsigned inline long m2();
// CHECK-MESSAGES: :[[@LINE-1]]:67: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} friend constexpr inline auto m2() -> const long int volatile unsigned long;{{$}}
int virtual unsigned m3();
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto m3() -> int unsigned;{{$}}
template <typename T>
int friend unsigned m4();
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} friend auto m4() -> int unsigned;{{$}}
};
//
// Functions in namespaces
//
namespace N {
int e1();
}
// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto e1() -> int;{{$}}
int N::e1() {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto N::e1() -> int {}{{$}}
//
// Functions with unsupported return types
//
int (*e3())(double);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}int (*e3())(double);{{$}}
struct A;
int A::* e5();
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}int A::* e5();{{$}}
int std::vector<std::string>::* e6();
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}int std::vector<std::string>::* e6();{{$}}
int (std::vector<std::string>::*e7())(double);
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}int (std::vector<std::string>::*e7())(double);{{$}}
//
// Functions with complex return types
//
inline volatile const std::vector<std::string> e2();
// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto e2() -> volatile const std::vector<std::string>;{{$}}
inline const std::vector<std::string> volatile e2();
// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto e2() -> const std::vector<std::string> volatile;{{$}}
inline std::vector<std::string> const volatile e2();
// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}inline auto e2() -> std::vector<std::string> const volatile;{{$}}
int* e8();
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto e8() -> int*;{{$}}
static const char* e9(void* user_data);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto e9(void* user_data) -> const char*;{{$}}
static const char* const e10(void* user_data);
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto e10(void* user_data) -> const char* const;{{$}}
static const char** volatile * const & e11(void* user_data);
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto e11(void* user_data) -> const char** volatile * const &;{{$}}
static const char* const * const * const e12(void* user_data);
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}static auto e12(void* user_data) -> const char* const * const * const;{{$}}
struct A e13();
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto e13() -> struct A;{{$}}
//
// decltype (unsupported if top level expression)
//
decltype(1 + 2) dec1() { return 1 + 2; }
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// TODO: source range of DecltypeTypeLoc not yet implemented
// _HECK-FIXES: {{^}}auto dec1() -> decltype(1 + 2) { return 1 + 2; }{{$}}
template <typename F, typename T>
decltype(std::declval<F>(std::declval<T>)) dec2(F f, T t) { return f(t); }
// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// TODO: source range of DecltypeTypeLoc not yet implemented
// _HECK-FIXES: {{^}}auto dec2(F f, T t) -> decltype(std::declval<F>(std::declval<T>)) { return f(t); }{{$}}
template <typename T>
typename decltype(std::declval<T>())::value_type dec3();
// CHECK-MESSAGES: :[[@LINE-1]]:50: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto dec3() -> typename decltype(std::declval<T>())::value_type;{{$}}
template <typename T>
decltype(std::declval<T>())* dec4();
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto dec4() -> decltype(std::declval<T>())*;{{$}}
//
// Methods
//
struct B {
B& operator=(const B&);
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto operator=(const B&) -> B&;{{$}}
double base1(int, bool b);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto base1(int, bool b) -> double;{{$}}
virtual double base2(int, bool b) {}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto base2(int, bool b) -> double {}{{$}}
virtual float base3() const = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto base3() const -> float = 0;{{$}}
virtual float base4() volatile = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto base4() volatile -> float = 0;{{$}}
double base5(int, bool b) &&;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto base5(int, bool b) && -> double;{{$}}
double base6(int, bool b) const &&;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto base6(int, bool b) const && -> double;{{$}}
double base7(int, bool b) const & = delete;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto base7(int, bool b) const & -> double = delete;{{$}}
double base8(int, bool b) const volatile & = delete;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto base8(int, bool b) const volatile & -> double = delete;{{$}}
virtual const char * base9() const noexcept { return ""; }
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto base9() const noexcept -> const char * { return ""; }{{$}}
};
double B::base1(int, bool b) {}
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto B::base1(int, bool b) -> double {}{{$}}
struct D : B {
virtual double f1(int, bool b) final;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto f1(int, bool b) -> double final;{{$}}
virtual double base2(int, bool b) override;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto base2(int, bool b) -> double override;{{$}}
virtual float base3() const override final { }
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} virtual auto base3() const -> float override final { }{{$}}
const char * base9() const noexcept override { return ""; }
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto base9() const noexcept -> const char * override { return ""; }{{$}}
int f2() __restrict;
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto f2() __restrict -> int;{{$}}
volatile int* __restrict f3() const __restrict noexcept;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto f3() const __restrict noexcept -> volatile int* __restrict;{{$}}
};
//
// Functions with attributes
//
int g1() [[asdf]];
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto g1() -> int {{[[][[]}}asdf{{[]][]]}};{{$}}
[[noreturn]] int g2();
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}{{[[][[]}}noreturn{{[]][]]}} auto g2() -> int;{{$}}
int g2 [[noreturn]] ();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto g2 {{[[][[]}}noreturn{{[]][]]}} () -> int;{{$}}
int unsigned g3() __attribute__((cdecl)); // FunctionTypeLoc is null.
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
int unsigned __attribute__((cdecl)) g3() ; // FunctionTypeLoc is null.
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
__attribute__((cdecl)) int unsigned g3() ; // FunctionTypeLoc is null.
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
//
// Templates
//
template <typename Container>
[[maybe_unused]] typename Container::value_type const volatile&& t1(Container& C) noexcept;
// CHECK-MESSAGES: :[[@LINE-1]]:66: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}{{[[][[]}}maybe_unused{{[]][]]}} auto t1(Container& C) noexcept -> typename Container::value_type const volatile&&;{{$}}
template <typename T>
class BB {
using type = int;
template <typename U>
typename BB<U>::type m1();
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto m1() -> typename BB<U>::type;{{$}}
};
//
// Macros
//
#define DWORD unsigned int
DWORD h1();
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h1() -> DWORD;{{$}}
#define INT int
#define UNSIGNED unsigned
UNSIGNED INT h2();
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h2() -> UNSIGNED INT;{{$}}
#define CONST const
CONST int h3();
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h3() -> CONST int;{{$}}
#define ALWAYS_INLINE inline
#define DLL_EXPORT __declspec(dllexport)
ALWAYS_INLINE DLL_EXPORT int h4();
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}ALWAYS_INLINE DLL_EXPORT auto h4() -> int;{{$}}
#define DEPRECATED __attribute__((deprecated))
int h5() DEPRECATED;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h5() -> int DEPRECATED;{{$}}
int DEPRECATED h5();
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto DEPRECATED h5() -> int;{{$}}
DEPRECATED int h5();
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}DEPRECATED auto h5() -> int;{{$}}
[[noreturn]] [[nodiscard]] DEPRECATED DLL_EXPORT int h6 [[deprecated]] ();
// CHECK-MESSAGES: :[[@LINE-1]]:54: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}{{[[][[]}}noreturn{{[]][]]}} {{[[][[]}}nodiscard{{[]][]]}} DEPRECATED DLL_EXPORT auto h6 {{[[][[]}}deprecated{{[]][]]}} () -> int;{{$}}
#define FUNCTION_NAME(a, b) a##b
int FUNCTION_NAME(foo, bar)();
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto FUNCTION_NAME(foo, bar)() -> int;{{$}}
#define DEFINE_FUNCTION_1(a, b) int a##b()
DEFINE_FUNCTION_1(foo, bar);
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
#define DEFINE_FUNCTION_2 int foo(int arg);
DEFINE_FUNCTION_2
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
#define DLL_EXPORT_const __declspec(dllexport) const
DLL_EXPORT_const int h7();
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
#define DLL_EXPORT_CONST __declspec(dllexport) CONST
DLL_EXPORT_CONST int h7();
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
template <typename T>
using Real = T;
#define PRECISION float
Real<PRECISION> h8() { return 0.; }
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h8() -> Real<PRECISION> { return 0.; }{{$}}
#define MAYBE_UNUSED_MACRO [[maybe_unused]]
template <typename Container>
MAYBE_UNUSED_MACRO typename Container::value_type const volatile** const h9(Container& C) noexcept;
// CHECK-MESSAGES: :[[@LINE-1]]:74: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}MAYBE_UNUSED_MACRO auto h9(Container& C) noexcept -> typename Container::value_type const volatile** const;{{$}}
#define NOEXCEPT noexcept
int h9(int arg) NOEXCEPT;
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h9(int arg) NOEXCEPT -> int;{{$}}
#define STATIC_INT static int
STATIC_INT h10();
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
#define UNSIGNED_STATIC_INT unsigned static int
UNSIGNED_STATIC_INT h11();
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
#define STATIC static
unsigned STATIC int h11();
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}STATIC auto h11() -> unsigned int;{{$}}
#define STATIC_CONSTEXPR static constexpr
unsigned STATIC_CONSTEXPR int h12();
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}STATIC_CONSTEXPR auto h12() -> unsigned int;{{$}}
#define STATIC_CONSTEXPR_LONG static constexpr long
unsigned STATIC_CONSTEXPR_LONG int h13();
// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
DEPRECATED const int& h14();
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}DEPRECATED auto h14() -> const int&;{{$}}
DEPRECATED const long static volatile unsigned& h15();
// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}DEPRECATED static auto h15() -> const long volatile unsigned&;{{$}}
#define WRAP(x) x
WRAP(const) int& h16();
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
WRAP(CONST) int& h16();
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
#define CONCAT(a, b) a##b
CONCAT(con, st) int& h16();
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
DEPRECATED const UNSIGNED& h17();
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}DEPRECATED auto h17() -> const UNSIGNED&;{{$}}
DEPRECATED CONST UNSIGNED STATIC& h18();
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}DEPRECATED STATIC auto h18() -> CONST UNSIGNED &;{{$}}
#define CONST_CAT con##st
CONST_CAT int& h19();
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h19() -> CONST_CAT int&;{{$}}
#define CONST_F_MACRO WRAP(CONST_CAT)
CONST_F_MACRO int& h19();
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto h19() -> CONST_F_MACRO int&;{{$}}
//
// Name collisions
//
struct Object { long long value; };
Object j1(unsigned Object) { return {Object * 2}; }
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}Object j1(unsigned Object) { return {Object * 2}; }{{$}}
::Object j1(unsigned Object);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto j1(unsigned Object) -> ::Object;{{$}}
const Object& j2(unsigned a, int b, char Object, long l);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}const Object& j2(unsigned a, int b, char Object, long l);{{$}}
const struct Object& j2(unsigned a, int b, char Object, long l);
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto j2(unsigned a, int b, char Object, long l) -> const struct Object&;{{$}}
std::vector<Object> j3(unsigned Object);
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}std::vector<Object> j3(unsigned Object);{{$}}
std::vector<const Object> j7(unsigned Object);
// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}std::vector<const Object> j7(unsigned Object);{{$}}
std::vector<Object> j4(unsigned vector);
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto j4(unsigned vector) -> std::vector<Object>;{{$}}
std::vector<::Object> j4(unsigned vector);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto j4(unsigned vector) -> std::vector<::Object>;{{$}}
std::vector<struct Object> j4(unsigned vector);
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto j4(unsigned vector) -> std::vector<struct Object>;{{$}}
std::vector<Object> j4(unsigned Vector);
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto j4(unsigned Vector) -> std::vector<Object>;{{$}}
using std::vector;
vector<Object> j5(unsigned vector);
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}vector<Object> j5(unsigned vector);{{$}}
constexpr auto Size = 5;
std::array<int, Size> j6(unsigned Size);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}std::array<int, Size> j6(unsigned Size);{{$}}
std::array<decltype(Size), (Size * 2) + 1> j8(unsigned Size);
// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}std::array<decltype(Size), (Size * 2) + 1> j8(unsigned Size);{{$}}
class CC {
int Object;
struct Object m();
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto m() -> struct Object;{{$}}
};
Object CC::m() { return {0}; }
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto CC::m() -> Object { return {0}; }{{$}}
class DD : public CC {
::Object g();
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}} auto g() -> ::Object;{{$}}
};
Object DD::g() {
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use a trailing return type for this function [modernize-use-trailing-return-type]
// CHECK-FIXES: {{^}}auto DD::g() -> Object {{{$}}
return {0};
}
//
// Samples which do not trigger the check
//
auto f() -> int;
auto f(int) -> int;
auto f(int arg) -> int;
auto f(int arg1, int arg2, int arg3) -> int;
auto f(int arg1, int arg2, int arg3, ...) -> int;
template <typename T> auto f(T t) -> int;
auto ff();
decltype(auto) fff();
void c();
void c(int arg);
void c(int arg) { return; }
struct D2 : B {
D2();
virtual ~D2();
virtual auto f1(int, bool b) -> double final;
virtual auto base2(int, bool b) -> double override;
virtual auto base3() const -> float override final { }
operator double();
};
auto l1 = [](int arg) {};
auto l2 = [](int arg) -> double {};