// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-return-braced-init-list %t
namespace std {
typedef decltype(sizeof(int)) size_t;
// libc++'s implementation
template <class _E>
class initializer_list {
const _E *__begin_;
size_t __size_;
initializer_list(const _E *__b, size_t __s)
: __begin_(__b),
__size_(__s) {}
public:
typedef _E value_type;
typedef const _E &reference;
typedef const _E &const_reference;
typedef size_t size_type;
typedef const _E *iterator;
typedef const _E *const_iterator;
initializer_list() : __begin_(nullptr), __size_(0) {}
size_t size() const { return __size_; }
const _E *begin() const { return __begin_; }
const _E *end() const { return __begin_ + __size_; }
};
template <typename T>
struct allocator {};
template <typename T, typename Allocator = ::std::allocator<T>>
class vector {
public:
vector(T);
vector(size_t, T, const Allocator &alloc = Allocator());
vector(std::initializer_list<T>);
};
} // namespace std
class Bar {};
Bar b0;
class Foo {
public:
Foo(Bar) {}
explicit Foo(Bar, unsigned int) {}
Foo(unsigned int) {}
};
class Baz {
public:
Foo m() {
Bar bm;
return Foo(bm);
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid repeating the return type from the declaration; use a braced initializer list instead [modernize-return-braced-init-list]
// CHECK-FIXES: return {bm};
}
};
class Quux : public Foo {
public:
Quux(Bar bar) : Foo(bar) {}
Quux(unsigned, unsigned, unsigned k = 0) : Foo(k) {}
};
Foo f() {
Bar b1;
return Foo(b1);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {b1};
}
Foo f2() {
Bar b2;
return {b2};
}
auto f3() {
Bar b3;
return Foo(b3);
}
#define A(b) Foo(b)
Foo f4() {
Bar b4;
return A(b4);
}
Foo f5() {
Bar b5;
return Quux(b5);
}
Foo f6() {
Bar b6;
return Foo(b6, 1);
}
std::vector<int> vectorWithOneParameter() {
int i7 = 1;
return std::vector<int>(i7);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
}
std::vector<int> vectorIntWithTwoParameter() {
return std::vector<int>(1, 2);
}
std::vector<double> vectorDoubleWithTwoParameter() {
return std::vector<double>(1, 2.1);
}
struct A {};
std::vector<A> vectorRecordWithTwoParameter() {
A a{};
return std::vector<A>(1, a);
}
Bar f8() {
return {};
}
Bar f9() {
return Bar();
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
}
Bar f10() {
return Bar{};
}
Foo f11(Bar b11) {
return Foo(b11);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {b11};
}
Foo f12() {
return f11(Bar());
}
Foo f13() {
return Foo(Bar()); // 13
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {Bar()}; // 13
}
Foo f14() {
// FIXME: Type narrowing should not occur!
return Foo(-1);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {-1};
}
Foo f15() {
return Foo(f10());
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {f10()};
}
Quux f16() {
return Quux(1, 2);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {1, 2};
}
Quux f17() {
return Quux(1, 2, 3);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
// CHECK-FIXES: return {1, 2, 3};
}
template <typename T>
T f19() {
return T();
}
Bar i1 = f19<Bar>();
Baz i2 = f19<Baz>();
template <typename T>
Foo f20(T t) {
return Foo(t);
}
Foo i3 = f20(b0);
template <typename T>
class BazT {
public:
T m() {
Bar b;
return T(b);
}
Foo m2(T t) {
return Foo(t);
}
};
BazT<Foo> bazFoo;
Foo i4 = bazFoo.m();
Foo i5 = bazFoo.m2(b0);
BazT<Quux> bazQuux;
Foo i6 = bazQuux.m();
Foo i7 = bazQuux.m2(b0);
auto v1 = []() { return std::vector<int>({1, 2}); }();
auto v2 = []() -> std::vector<int> { return std::vector<int>({1, 2}); }();