@@ -32,7 +32,14 @@ array<int[4], 2> d;
3232using k = int [4 ];
3333// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use 'std::array' instead
3434
35+ k ak;
36+ // no diagnostic expected here since no concrete c-array type is written here
37+
3538array<k, 2 > dk;
39+ // no diagnostic expected here since no concrete c-array type is written here
40+
41+ array<decltype (ak), 3 > ek;
42+ // no diagnostic expected here since no concrete c-array type is written here
3643
3744template <typename T>
3845class unique_ptr {
@@ -92,3 +99,173 @@ const char name[] = "Some string";
9299
93100void takeCharArray (const char name[]);
94101// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: do not declare C-style arrays, use 'std::array' or 'std::vector' instead [modernize-avoid-c-arrays]
102+
103+ namespace std {
104+ template <class T , class U >
105+ struct is_same { constexpr static bool value{false }; };
106+
107+ template <class T >
108+ struct is_same <T, T> { constexpr static bool value{true }; };
109+
110+ template <class T , class U >
111+ constexpr bool is_same_v = is_same<T, U>::value;
112+
113+ template <class T > struct remove_const { typedef T type; };
114+ template <class T > struct remove_const <const T> { typedef T type; };
115+
116+ template <class T >
117+ using remove_const_t = typename remove_const<T>::type;
118+
119+ template <bool B, class T = void > struct enable_if {};
120+ template <class T > struct enable_if <true , T> { typedef T type; };
121+
122+ template < bool B, class T = void >
123+ using enable_if_t = typename enable_if<B, T>::type;
124+ }
125+
126+ // below, no array type findings are expected within the template parameter declarations since no array type gets written explicitly
127+ template <typename T,
128+ bool = std::is_same_v<T, int >,
129+ bool = std::is_same<T, int >::value,
130+ bool = std::is_same_v<std::remove_const_t <T>, int >,
131+ bool = std::is_same<std::remove_const_t <T>, int >::value,
132+ bool = std::is_same_v<typename std::remove_const<T>::type, int >,
133+ bool = std::is_same<typename std::remove_const<T>::type, int >::value,
134+ std::enable_if_t <not (std::is_same_v<std::remove_const_t <T>, int >) && not (std::is_same_v<typename std::remove_const<T>::type, char >), bool > = true ,
135+ typename std::enable_if<not (std::is_same_v<std::remove_const_t <T>, int >) && not (std::is_same_v<typename std::remove_const<T>::type, char >), bool >::type = true ,
136+ typename = std::enable_if_t <not (std::is_same_v<std::remove_const_t <T>, int >) && not (std::is_same_v<typename std::remove_const<T>::type, char >)>,
137+ typename = typename std::remove_const<T>::type,
138+ typename = std::remove_const_t <T>>
139+ class MyClassTemplate {
140+ public:
141+ // here, plenty of array type findings are expected for below template parameter declarations since array types get written explicitly
142+ template <typename U = T,
143+ bool = std::is_same_v<U, int []>,
144+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
145+ bool = std::is_same<U, int [10 ]>::value,
146+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
147+ std::enable_if_t <not (std::is_same_v<std::remove_const_t <U>, int []>) && not (std::is_same_v<typename std::remove_const<U>::type, char [10 ]>), bool > = true ,
148+ // CHECK-MESSAGES: :[[@LINE-1]]:73: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
149+ // CHECK-MESSAGES: :[[@LINE-2]]:140: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
150+ typename = typename std::remove_const<int [10 ]>::type,
151+ // CHECK-MESSAGES: :[[@LINE-1]]:51: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
152+ typename = std::remove_const_t <int []>>
153+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
154+ class MyInnerClassTemplate {
155+ public:
156+ MyInnerClassTemplate (const U&) {}
157+ private:
158+ U field[3 ];
159+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
160+ };
161+
162+ MyClassTemplate (const T&) {}
163+
164+ private:
165+ T field[7 ];
166+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
167+ };
168+
169+ // an explicit instantiation
170+ template
171+ class MyClassTemplate <int [2 ]>;
172+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
173+
174+ using MyArrayType = int [3 ];
175+ // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
176+
177+ // another explicit instantiation
178+ template
179+ class MyClassTemplate <MyArrayType>;
180+
181+ // below, no array type findings are expected within the template parameter declarations since no array type gets written explicitly
182+ template <typename T,
183+ bool = std::is_same_v<T, int >,
184+ bool = std::is_same<T, int >::value,
185+ bool = std::is_same_v<std::remove_const_t <T>, int >,
186+ bool = std::is_same<std::remove_const_t <T>, int >::value,
187+ bool = std::is_same_v<typename std::remove_const<T>::type, int >,
188+ bool = std::is_same<typename std::remove_const<T>::type, int >::value,
189+ std::enable_if_t <not (std::is_same_v<std::remove_const_t <T>, int >) && not (std::is_same_v<typename std::remove_const<T>::type, char >), bool > = true ,
190+ typename std::enable_if<not (std::is_same_v<std::remove_const_t <T>, int >) && not (std::is_same_v<typename std::remove_const<T>::type, char >), bool >::type = true ,
191+ typename = std::enable_if_t <not (std::is_same_v<std::remove_const_t <T>, int >) && not (std::is_same_v<typename std::remove_const<T>::type, char >)>,
192+ typename = typename std::remove_const<T>::type,
193+ typename = std::remove_const_t <T>>
194+ void func (const T& param) {
195+ int array1[1 ];
196+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
197+
198+ T array2[2 ];
199+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
200+
201+ T value;
202+ }
203+
204+ // here, plenty of array type findings are expected for below template parameter declarations since array types get written explicitly
205+ template <typename T = int [],
206+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
207+ bool = std::is_same_v<T, int []>,
208+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
209+ bool = std::is_same<T, int [10 ]>::value,
210+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
211+ std::enable_if_t <not (std::is_same_v<std::remove_const_t <T>, int []>) && not (std::is_same_v<typename std::remove_const<T>::type, char [10 ]>), bool > = true ,
212+ // CHECK-MESSAGES: :[[@LINE-1]]:71: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
213+ // CHECK-MESSAGES: :[[@LINE-2]]:138: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
214+ typename = typename std::remove_const<int [10 ]>::type,
215+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
216+ typename = std::remove_const_t <int []>>
217+ // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
218+ void fun (const T& param) {
219+ int array3[3 ];
220+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
221+
222+ T array4[4 ];
223+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
224+
225+ T value;
226+ }
227+
228+ template <typename T>
229+ T some_constant{};
230+
231+ // explicit instantiations
232+ template
233+ int some_constant<int [5 ]>[5 ];
234+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
235+
236+ template
237+ int some_constant<decltype (ak)>[4 ];
238+ // FIXME: why no diagnostic here?
239+
240+ MyArrayType mk;
241+ // no diagnostic expected here since no concrete c-array type is written here
242+
243+ // explicit specializations
244+ template <>
245+ int some_constant<int [7 ]>[7 ]{};
246+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
247+ // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
248+
249+ template <>
250+ int some_constant<decltype (mk)>[3 ]{};
251+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
252+
253+ void testArrayInTemplateType () {
254+ int t[10 ];
255+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use 'std::array' instead [modernize-avoid-c-arrays]
256+
257+ func (t);
258+ fun (t);
259+
260+ func<decltype (t)>({});
261+ fun<decltype (t)>({});
262+
263+ MyClassTemplate var1{t};
264+ MyClassTemplate<decltype (t)> var2{{}};
265+
266+ decltype (var1)::MyInnerClassTemplate var3{t};
267+ decltype (var1)::MyInnerClassTemplate<decltype (t)> var4{{}};
268+
269+ MyClassTemplate<decltype (t)>::MyInnerClassTemplate var5{t};
270+ MyClassTemplate<decltype (t)>::MyInnerClassTemplate<decltype (t)> var6{{}};
271+ }
0 commit comments