[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-unsafe-buffer-usage-in-container-span-construct.cpp
blob638c76c58c0250cc4d8204cf508127a927d3c5bd
1 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage-in-container -verify %s
3 namespace std {
4 template <class T> class span {
5 public:
6 constexpr span(T *, unsigned){}
8 template<class Begin, class End>
9 constexpr span(Begin first, End last){}
11 T * data();
13 constexpr span() {};
15 constexpr span(const std::span<T> &span) {};
17 template<class R>
18 constexpr span(R && range){};
22 template< class T >
23 T&& move( T&& t ) noexcept;
25 template <class _Tp>
26 _Tp* addressof(_Tp& __x) {
27 return &__x;
32 namespace irrelevant_constructors {
33 void non_two_param_constructors() {
34 class Array {
35 } a;
36 std::span<int> S; // no warn
37 std::span<int> S1{}; // no warn
38 std::span<int> S2{std::move(a)}; // no warn
39 std::span<int> S3{S2}; // no warn
41 } // irrelevant_constructors
43 namespace construct_wt_ptr_size {
44 std::span<int> warnVarInit(int *p) {
45 std::span<int> S{p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
46 std::span<int> S1(p, 10); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
47 std::span<int> S2 = std::span{p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
48 std::span<int> S3 = std::span(p, 10); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
49 std::span<int> S4 = std::span<int>{p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
50 std::span<int> S5 = std::span<int>(p, 10); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
51 std::span<int> S6 = {p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
52 auto S7 = std::span<int>{p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
53 auto S8 = std::span<int>(p, 10); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
54 const auto &S9 = std::span<int>{p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
55 auto &&S10 = std::span<int>(p, 10); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
57 #define Ten 10
59 std::span S11 = std::span<int>{p, Ten}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
61 if (auto X = std::span<int>{p, Ten}; S10.data()) { // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
64 auto X = warnVarInit(p); // function return is fine
65 return S;
68 template<typename T>
69 void foo(const T &, const T &&, T);
71 std::span<int> warnTemp(int *p) {
72 foo(std::span<int>{p, 10}, // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
73 std::move(std::span<int>{p, 10}), // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
74 std::span<int>{p, 10}); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
76 std::span<int> Arr[1] = {std::span<int>{p, 10}}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
78 if (std::span<int>{p, 10}.data()) { // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
80 return std::span<int>{p, 10}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
83 // addressof method defined outside std namespace.
84 template <class _Tp>
85 _Tp* addressof(_Tp& __x) {
86 return &__x;
89 void notWarnSafeCases(unsigned n, int *p) {
90 int X;
91 unsigned Y = 10;
92 std::span<int> S = std::span{&X, 1}; // no-warning
93 S = std::span{std::addressof(X), 1}; // no-warning
94 int Arr[10];
95 typedef int TenInts_t[10];
96 TenInts_t Arr2;
98 S = std::span{&X, 2}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
99 S = std::span{std::addressof(X), 2}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
100 // Warn when a non std method also named addressof
101 S = std::span{addressof(X), 1}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
103 S = std::span{new int[10], 10}; // no-warning
104 S = std::span{new int[n], n}; // no-warning
105 S = std::span{new int, 1}; // no-warning
106 S = std::span{new int, X}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
107 S = std::span{new int[n--], n--}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
108 S = std::span{new int[10], 11}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
109 S = std::span{new int[10], 9}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe
110 S = std::span{new int[10], Y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe
111 S = std::span{Arr, 10}; // no-warning
112 S = std::span{Arr2, 10}; // no-warning
113 S = std::span{Arr, Y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe
114 S = std::span{p, 0}; // no-warning
116 } // namespace construct_wt_ptr_size
118 namespace construct_wt_begin_end {
119 class It {};
121 std::span<int> warnVarInit(It &First, It &Last) {
122 std::span<int> S{First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
123 std::span<int> S1(First, Last); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
124 std::span<int> S2 = std::span<int>{First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
125 std::span<int> S3 = std::span<int>(First, Last); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
126 std::span<int> S4 = std::span<int>{First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
127 std::span<int> S5 = std::span<int>(First, Last); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
128 std::span<int> S6 = {First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
129 auto S7 = std::span<int>{First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
130 auto S8 = std::span<int>(First, Last); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
131 const auto &S9 = std::span<int>{First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
132 auto &&S10 = std::span<int>(First, Last); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
134 if (auto X = std::span<int>{First, Last}; S10.data()) { // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
137 auto X = warnVarInit(First, Last); // function return is fine
138 return S;
141 template<typename T>
142 void foo(const T &, const T &&, T);
144 std::span<int> warnTemp(It &First, It &Last) {
145 foo(std::span<int>{First, Last}, // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
146 std::move(std::span<int>{First, Last}), // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
147 std::span<int>{First, Last}); // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
149 std::span<int> Arr[1] = {std::span<int>{First, Last}}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
151 if (std::span<int>{First, Last}.data()) { // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
153 return std::span<int>{First, Last}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
155 } // namespace construct_wt_begin_end
157 namespace test_flag {
158 void f(int *p) {
159 #pragma clang diagnostic push
160 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // this flag turns off every unsafe-buffer warning
161 std::span<int> S{p, 10}; // no-warning
162 p++; // no-warning
163 #pragma clang diagnostic pop
165 #pragma clang diagnostic push
166 #pragma clang diagnostic warning "-Wunsafe-buffer-usage"
167 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
168 // turn on all unsafe-buffer warnings except for the ones under `-Wunsafe-buffer-usage-in-container`
169 std::span<int> S2{p, 10}; // no-warning
171 p++; // expected-warning{{unsafe pointer arithmetic}}\
172 expected-note{{pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions}}
173 #pragma clang diagnostic pop
176 } //namespace test_flag