1 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage-in-container -verify %s
4 template <class T
> class span
{
6 constexpr span(T
*, unsigned){}
8 template<class Begin
, class End
>
9 constexpr span(Begin first
, End last
){}
15 constexpr span(const std::span
<T
> &span
) {};
18 constexpr span(R
&& range
){};
23 T
&& move( T
&& t
) noexcept
;
26 _Tp
* addressof(_Tp
& __x
) {
32 namespace irrelevant_constructors
{
33 void non_two_param_constructors() {
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}}
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
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.
85 _Tp
* addressof(_Tp
& __x
) {
89 void notWarnSafeCases(unsigned n
, int *p
) {
92 std::span
<int> S
= std::span
{&X
, 1}; // no-warning
93 S
= std::span
{std::addressof(X
), 1}; // no-warning
95 typedef int TenInts_t
[10];
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
{
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
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
{
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
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