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 | |
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 | |
25 | initializer_list() : __begin_(nullptr), __size_(0) {} |
26 | |
27 | size_t size() const { return __size_; } |
28 | const _E *begin() const { return __begin_; } |
29 | const _E *end() const { return __begin_ + __size_; } |
30 | }; |
31 | |
32 | template <typename T> |
33 | struct allocator {}; |
34 | |
35 | template <typename T, typename Allocator = ::std::allocator<T>> |
36 | class vector { |
37 | public: |
38 | vector(T); |
39 | vector(size_t, T, const Allocator &alloc = Allocator()); |
40 | vector(std::initializer_list<T>); |
41 | }; |
42 | } // namespace std |
43 | |
44 | class Bar {}; |
45 | |
46 | Bar b0; |
47 | |
48 | class Foo { |
49 | public: |
50 | Foo(Bar) {} |
51 | explicit Foo(Bar, unsigned int) {} |
52 | Foo(unsigned int) {} |
53 | }; |
54 | |
55 | class Baz { |
56 | public: |
57 | Foo m() { |
58 | Bar bm; |
59 | return Foo(bm); |
60 | // 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] |
61 | // CHECK-FIXES: return {bm}; |
62 | } |
63 | }; |
64 | |
65 | class Quux : public Foo { |
66 | public: |
67 | Quux(Bar bar) : Foo(bar) {} |
68 | Quux(unsigned, unsigned, unsigned k = 0) : Foo(k) {} |
69 | }; |
70 | |
71 | Foo f() { |
72 | Bar b1; |
73 | return Foo(b1); |
74 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
75 | // CHECK-FIXES: return {b1}; |
76 | } |
77 | |
78 | Foo f2() { |
79 | Bar b2; |
80 | return {b2}; |
81 | } |
82 | |
83 | auto f3() { |
84 | Bar b3; |
85 | return Foo(b3); |
86 | } |
87 | |
88 | #define A(b) Foo(b) |
89 | |
90 | Foo f4() { |
91 | Bar b4; |
92 | return A(b4); |
93 | } |
94 | |
95 | Foo f5() { |
96 | Bar b5; |
97 | return Quux(b5); |
98 | } |
99 | |
100 | Foo f6() { |
101 | Bar b6; |
102 | return Foo(b6, 1); |
103 | } |
104 | |
105 | std::vector<int> vectorWithOneParameter() { |
106 | int i7 = 1; |
107 | return std::vector<int>(i7); |
108 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
109 | } |
110 | |
111 | std::vector<int> vectorIntWithTwoParameter() { |
112 | return std::vector<int>(1, 2); |
113 | } |
114 | |
115 | std::vector<double> vectorDoubleWithTwoParameter() { |
116 | return std::vector<double>(1, 2.1); |
117 | } |
118 | struct A {}; |
119 | std::vector<A> vectorRecordWithTwoParameter() { |
120 | A a{}; |
121 | return std::vector<A>(1, a); |
122 | } |
123 | |
124 | |
125 | Bar f8() { |
126 | return {}; |
127 | } |
128 | |
129 | Bar f9() { |
130 | return Bar(); |
131 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
132 | } |
133 | |
134 | Bar f10() { |
135 | return Bar{}; |
136 | } |
137 | |
138 | Foo f11(Bar b11) { |
139 | return Foo(b11); |
140 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
141 | // CHECK-FIXES: return {b11}; |
142 | } |
143 | |
144 | Foo f12() { |
145 | return f11(b11: Bar()); |
146 | } |
147 | |
148 | Foo f13() { |
149 | return Foo(Bar()); // 13 |
150 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
151 | // CHECK-FIXES: return {Bar()}; // 13 |
152 | } |
153 | |
154 | Foo f14() { |
155 | // FIXME: Type narrowing should not occur! |
156 | return Foo(-1); |
157 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
158 | // CHECK-FIXES: return {-1}; |
159 | } |
160 | |
161 | Foo f15() { |
162 | return Foo(f10()); |
163 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
164 | // CHECK-FIXES: return {f10()}; |
165 | } |
166 | |
167 | Quux f16() { |
168 | return Quux(1, 2); |
169 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
170 | // CHECK-FIXES: return {1, 2}; |
171 | } |
172 | |
173 | Quux f17() { |
174 | return Quux(1, 2, 3); |
175 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type |
176 | // CHECK-FIXES: return {1, 2, 3}; |
177 | } |
178 | |
179 | template <typename T> |
180 | T f19() { |
181 | return T(); |
182 | } |
183 | |
184 | Bar i1 = f19<Bar>(); |
185 | Baz i2 = f19<Baz>(); |
186 | |
187 | template <typename T> |
188 | Foo f20(T t) { |
189 | return Foo(t); |
190 | } |
191 | |
192 | Foo i3 = f20(t: b0); |
193 | |
194 | template <typename T> |
195 | class BazT { |
196 | public: |
197 | T m() { |
198 | Bar b; |
199 | return T(b); |
200 | } |
201 | |
202 | Foo m2(T t) { |
203 | return Foo(t); |
204 | } |
205 | }; |
206 | |
207 | BazT<Foo> bazFoo; |
208 | Foo i4 = bazFoo.m(); |
209 | Foo i5 = bazFoo.m2(t: b0); |
210 | |
211 | BazT<Quux> bazQuux; |
212 | Foo i6 = bazQuux.m(); |
213 | Foo i7 = bazQuux.m2(t: b0); |
214 | |
215 | auto v1 = []() { return std::vector<int>({1, 2}); }(); |
216 | auto v2 = []() -> std::vector<int> { return std::vector<int>({1, 2}); }(); |
217 | |