189a1d03eSRichard // RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-array-to-pointer-decay %t 289a1d03eSRichard #include <stddef.h> 389a1d03eSRichard 489a1d03eSRichard namespace gsl { 589a1d03eSRichard template <class T> 689a1d03eSRichard class array_view { 789a1d03eSRichard public: 889a1d03eSRichard template <class U, size_t N> 989a1d03eSRichard array_view(U (&arr)[N]); 1089a1d03eSRichard }; 1189a1d03eSRichard } 1289a1d03eSRichard 1389a1d03eSRichard void pointerfun(int *p); 1489a1d03eSRichard void arrayfun(int p[]); 1589a1d03eSRichard void arrayviewfun(gsl::array_view<int> &p); 1689a1d03eSRichard size_t s(); 1789a1d03eSRichard f()1889a1d03eSRichardvoid f() { 1989a1d03eSRichard int a[5]; 2089a1d03eSRichard pointerfun(a); 2189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay] 2289a1d03eSRichard pointerfun((int *)a); // OK, explicit cast 2389a1d03eSRichard arrayfun(a); 2489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not implicitly decay an array into a pointer 2589a1d03eSRichard 2689a1d03eSRichard pointerfun(a + s() - 10); // Convert to &a[g() - 10]; 2789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not implicitly decay an array into a pointer 2889a1d03eSRichard 2989a1d03eSRichard gsl::array_view<int> av(a); 3089a1d03eSRichard arrayviewfun(av); // OK 3189a1d03eSRichard 3289a1d03eSRichard int i = a[0]; // OK 3389a1d03eSRichard int j = a[(1 + 2)];// OK 3489a1d03eSRichard pointerfun(&a[0]); // OK 3589a1d03eSRichard 3689a1d03eSRichard for (auto &e : a) // OK, iteration internally decays array to pointer 3789a1d03eSRichard e = 1; 3889a1d03eSRichard } 3989a1d03eSRichard g()4089a1d03eSRichardconst char *g() { 4189a1d03eSRichard return "clang"; // OK, decay string literal to pointer 4289a1d03eSRichard } g2()4389a1d03eSRichardconst char *g2() { 4489a1d03eSRichard return ("clang"); // OK, ParenExpr hides the literal-pointer decay 4589a1d03eSRichard } g3()46*9be33de4SCongcong Caiconst char *g3() { 47*9be33de4SCongcong Cai return __func__; // OK, don't diagnose PredefinedExpr 48*9be33de4SCongcong Cai } 4989a1d03eSRichard 5089a1d03eSRichard void f2(void *const *); bug25362()5189a1d03eSRichardvoid bug25362() { 5289a1d03eSRichard void *a[2]; 5389a1d03eSRichard f2(static_cast<void *const*>(a)); // OK, explicit cast 5489a1d03eSRichard } 5589a1d03eSRichard issue31155(int i)5689a1d03eSRichardvoid issue31155(int i) { 5789a1d03eSRichard const char *a = i ? "foo" : "bar"; // OK, decay string literal to pointer 5889a1d03eSRichard const char *b = i ? "foo" : "foobar"; // OK, decay string literal to pointer 5989a1d03eSRichard 6089a1d03eSRichard char arr[1]; 6189a1d03eSRichard const char *c = i ? arr : "bar"; 6289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: do not implicitly decay an array into a pointer 6389a1d03eSRichard const char *d = i ? "foo" : arr; 6489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: do not implicitly decay an array into a pointer 6589a1d03eSRichard } 66