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