@@ -119,16 +119,15 @@ struct HoldsUnsafeMembers {
119119
120120 [[clang::unsafe_buffer_usage]]
121121 HoldsUnsafeMembers (int i)
122- : FromCtor(i), // expected-warning{{function introduces unsafe buffer manipulation}}
123- FromCtor2{i} // expected-warning{{function introduces unsafe buffer manipulation}}
124- {}
122+ : FromCtor(i),
123+ FromCtor2{i} {}
125124
126125 HoldsUnsafeMembers (float f)
127126 : HoldsUnsafeMembers(0 ) {} // expected-warning{{function introduces unsafe buffer manipulation}}
128127
129128 UnsafeMembers FromCtor;
130129 UnsafeMembers FromCtor2;
131- UnsafeMembers FromField{3 }; // expected-warning 2 {{function introduces unsafe buffer manipulation}}
130+ UnsafeMembers FromField{3 }; // expected-warning {{function introduces unsafe buffer manipulation}}
132131};
133132
134133struct SubclassUnsafeMembers : public UnsafeMembers {
@@ -138,8 +137,7 @@ struct SubclassUnsafeMembers : public UnsafeMembers {
138137
139138 [[clang::unsafe_buffer_usage]]
140139 SubclassUnsafeMembers (int i)
141- : UnsafeMembers(i) // expected-warning{{function introduces unsafe buffer manipulation}}
142- {}
140+ : UnsafeMembers(i){}
143141};
144142
145143// https://github.com/llvm/llvm-project/issues/80482
@@ -245,3 +243,68 @@ struct AggregateViaDefaultInit {
245243void testAggregateViaDefaultInit () {
246244 AggregateViaDefaultInit A;
247245};
246+
247+ struct A {
248+ int arr[2 ];
249+
250+ [[clang::unsafe_buffer_usage]]
251+ int *ptr;
252+ };
253+
254+ namespace std {
255+ template <typename T> class span {
256+
257+ T *elements;
258+
259+ public:
260+
261+ constexpr span (T *, unsigned ){}
262+
263+ template <class Begin , class End >
264+ constexpr span (Begin first, End last){}
265+
266+ constexpr T* data () const noexcept {
267+ return elements;
268+ }
269+ };
270+ }
271+
272+ [[clang::unsafe_buffer_usage]]
273+ void check_no_warnings (unsigned idx) {
274+ int *arr = new int [20 ];
275+
276+ int k = arr[idx]; // no-warning
277+
278+ std::span<int > sp = {arr, 20 }; // no-warning
279+ A *ptr = reinterpret_cast <A*> (sp.data ()); // no-warning
280+ A a;
281+ a.ptr = arr; // no-warning
282+ }
283+
284+ [[clang::unsafe_buffer_usage]]
285+ void check_no_warning_variadic (unsigned idx, int arr[20 ], ...) {
286+ int k = arr[idx]; // no-warning
287+
288+ std::span<int > sp = {arr, 20 }; // no-warning
289+ A *ptr = reinterpret_cast <A*> (sp.data ()); // no-warning
290+ A a;
291+ a.ptr = arr; // no-warning
292+ }
293+
294+ template <typename T>
295+ [[clang::unsafe_buffer_usage]]
296+ void check_no_warnings_template (unsigned idx, T* arr) {
297+ int k = arr[idx]; // no-warning
298+
299+ std::span<int > sp = {arr, 20 }; // no-warning
300+ A *ptr = reinterpret_cast <A*> (sp.data ()); // no-warning
301+ A a;
302+ a.ptr = arr; // no-warning
303+ }
304+
305+ void invoke_methods () {
306+ int array[20 ];
307+ check_no_warnings (30 ); // expected-warning{{function introduces unsafe buffer manipulation}}
308+ check_no_warning_variadic (15 , array); // expected-warning{{function introduces unsafe buffer manipulation}}
309+ check_no_warnings_template (10 , array); // expected-warning{{function introduces unsafe buffer manipulation}}
310+ }
0 commit comments