1 // RUN: %check_clang_tidy -std=c++14-or-later %s modernize-return-braced-init-list %t
2
3 namespace std {
4 typedef decltype(sizeof(int)) size_t;
5
6 // libc++'s implementation
7 template <class _E>
8 class initializer_list {
9 const _E *__begin_;
10 size_t __size_;
11
initializer_list(const _E * __b,size_t __s)12 initializer_list(const _E *__b, size_t __s)
13 : __begin_(__b),
14 __size_(__s) {}
15
16 public:
17 typedef _E value_type;
18 typedef const _E &reference;
19 typedef const _E &const_reference;
20 typedef size_t size_type;
21
22 typedef const _E *iterator;
23 typedef const _E *const_iterator;
24
initializer_list()25 initializer_list() : __begin_(nullptr), __size_(0) {}
26
size() const27 size_t size() const { return __size_; }
begin() const28 const _E *begin() const { return __begin_; }
end() const29 const _E *end() const { return __begin_ + __size_; }
30 };
31
32 template <typename T>
33 class vector {
34 public:
vector(T)35 vector(T) {}
vector(std::initializer_list<T>)36 vector(std::initializer_list<T>) {}
37 };
38 }
39
40 class Bar {};
41
42 Bar b0;
43
44 class Foo {
45 public:
Foo(Bar)46 Foo(Bar) {}
Foo(Bar,unsigned int)47 explicit Foo(Bar, unsigned int) {}
Foo(unsigned int)48 Foo(unsigned int) {}
49 };
50
51 class Baz {
52 public:
m()53 Foo m() {
54 Bar bm;
55 return Foo(bm);
56 // 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]
57 // CHECK-FIXES: return {bm};
58 }
59 };
60
61 class Quux : public Foo {
62 public:
Quux(Bar bar)63 Quux(Bar bar) : Foo(bar) {}
Quux(unsigned,unsigned,unsigned k=0)64 Quux(unsigned, unsigned, unsigned k = 0) : Foo(k) {}
65 };
66
f()67 Foo f() {
68 Bar b1;
69 return Foo(b1);
70 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
71 // CHECK-FIXES: return {b1};
72 }
73
f2()74 Foo f2() {
75 Bar b2;
76 return {b2};
77 }
78
f3()79 auto f3() {
80 Bar b3;
81 return Foo(b3);
82 }
83
84 #define A(b) Foo(b)
85
f4()86 Foo f4() {
87 Bar b4;
88 return A(b4);
89 }
90
f5()91 Foo f5() {
92 Bar b5;
93 return Quux(b5);
94 }
95
f6()96 Foo f6() {
97 Bar b6;
98 return Foo(b6, 1);
99 }
100
f7()101 std::vector<int> f7() {
102 int i7 = 1;
103 return std::vector<int>(i7);
104 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
105 }
106
f8()107 Bar f8() {
108 return {};
109 }
110
f9()111 Bar f9() {
112 return Bar();
113 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
114 }
115
f10()116 Bar f10() {
117 return Bar{};
118 }
119
f11(Bar b11)120 Foo f11(Bar b11) {
121 return Foo(b11);
122 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
123 // CHECK-FIXES: return {b11};
124 }
125
f12()126 Foo f12() {
127 return f11(Bar());
128 }
129
f13()130 Foo f13() {
131 return Foo(Bar()); // 13
132 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
133 // CHECK-FIXES: return {Bar()}; // 13
134 }
135
f14()136 Foo f14() {
137 // FIXME: Type narrowing should not occur!
138 return Foo(-1);
139 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
140 // CHECK-FIXES: return {-1};
141 }
142
f15()143 Foo f15() {
144 return Foo(f10());
145 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
146 // CHECK-FIXES: return {f10()};
147 }
148
f16()149 Quux f16() {
150 return Quux(1, 2);
151 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
152 // CHECK-FIXES: return {1, 2};
153 }
154
f17()155 Quux f17() {
156 return Quux(1, 2, 3);
157 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
158 // CHECK-FIXES: return {1, 2, 3};
159 }
160
161 template <typename T>
f19()162 T f19() {
163 return T();
164 }
165
166 Bar i1 = f19<Bar>();
167 Baz i2 = f19<Baz>();
168
169 template <typename T>
f20(T t)170 Foo f20(T t) {
171 return Foo(t);
172 }
173
174 Foo i3 = f20(b0);
175
176 template <typename T>
177 class BazT {
178 public:
m()179 T m() {
180 Bar b;
181 return T(b);
182 }
183
m2(T t)184 Foo m2(T t) {
185 return Foo(t);
186 }
187 };
188
189 BazT<Foo> bazFoo;
190 Foo i4 = bazFoo.m();
191 Foo i5 = bazFoo.m2(b0);
192
193 BazT<Quux> bazQuux;
194 Foo i6 = bazQuux.m();
195 Foo i7 = bazQuux.m2(b0);
196
__anonc61550e40102() 197 auto v1 = []() { return std::vector<int>({1, 2}); }();
__anonc61550e40202() 198 auto v2 = []() -> std::vector<int> { return std::vector<int>({1, 2}); }();
199