22
33#include < ptrcheck.h>
44#include < stddef.h>
5+ #include < stdint.h>
56
67namespace std {
78template <typename T> struct span {
@@ -26,6 +27,10 @@ struct cb_multi {
2627 size_t n;
2728};
2829
30+ struct cb_nested {
31+ cb nested;
32+ };
33+
2934// Simple pointer and count
3035
3136void good_null (int *__counted_by (count) p, int count) {
@@ -118,6 +123,16 @@ void good_null_loop_if(int *__counted_by(count) p, int count) {
118123 }
119124}
120125
126+ void good_size_bytes_char (char *__counted_by (count) p, size_t count, std::span<char> sp) {
127+ p = sp.data ();
128+ count = sp.size_bytes ();
129+ }
130+
131+ void good_size_bytes_void (void *__sized_by (size) p, size_t size, std::span<uint8_t> sp) {
132+ p = sp.data ();
133+ size = sp.size_bytes ();
134+ }
135+
121136// Simple pointer and count in struct
122137
123138void good_struct_self (cb *c) {
@@ -167,6 +182,54 @@ void good_struct_self_loop(cb *c) {
167182 }
168183}
169184
185+ void good_struct_nested_span (cb_nested *n, std::span<int > sp) {
186+ n->nested .p = sp.data ();
187+ n->nested .count = sp.size ();
188+ }
189+
190+ void bad_struct_nested_span (cb_nested *n, std::span<int > sp, size_t unrelated_size) {
191+ n->nested .p = sp.data (); // expected-warning{{unsafe assignment to count-attributed pointer}}
192+ n->nested .count = unrelated_size;
193+ }
194+
195+ class struct_test {
196+ int *__counted_by (count_) data_;
197+ size_t count_;
198+ cb cb_;
199+ cb_nested nested_;
200+ cb *p_cb_;
201+
202+ void set_data (std::span<int > sp) {
203+ data_ = sp.data ();
204+ count_ = sp.size ();
205+ }
206+
207+ void bad_set_data (std::span<int > sp) {
208+ data_ = sp.data (); // expected-warning{{unsafe assignment to count-attributed pointer}}
209+ count_ = 42 ;
210+ }
211+
212+ void set_cb (std::span<int > sp) {
213+ cb_.p = sp.data ();
214+ cb_.count = sp.size ();
215+ }
216+
217+ void bad_set_cb (std::span<int > sp) {
218+ cb_.p = sp.data (); // expected-warning{{unsafe assignment to count-attributed pointer}}
219+ cb_.count = 42 ;
220+ }
221+
222+ void set_nested (std::span<int > sp) {
223+ nested_.nested .p = sp.data ();
224+ nested_.nested .count = sp.size ();
225+ }
226+
227+ void set_p_cb (std::span<int > sp) {
228+ p_cb_->p = sp.data ();
229+ p_cb_->count = sp.size ();
230+ }
231+ };
232+
170233// Pointer with multiple counts
171234
172235void bad_multicounts_span (int *__counted_by (a + b) p, size_t a, size_t b, std::span<int> sp) {
@@ -249,6 +312,16 @@ bool good_multicount_struct_realistic(cb_multi *cbm, std::span<int> sp, size_t s
249312 return true ;
250313}
251314
315+ struct multicount_struct_test {
316+ cb_multi multi_;
317+
318+ void set_multi (std::span<int > sp, size_t a, size_t b) {
319+ multi_.p = sp.first (a * b).data ();
320+ multi_.m = a;
321+ multi_.n = b;
322+ }
323+ };
324+
252325// Multiple pointers
253326
254327void good_multiptr_span (int *__counted_by (count) p, int *__counted_by(count) q, size_t count, std::span<int> sp) {
@@ -552,6 +625,37 @@ void missing_struct_unrelated(cb *c, cb *d) {
552625 d->count = 0 ; // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'p' missing}}
553626}
554627
628+ void missing_struct_nested_ptr (cb_nested *c) {
629+ c->nested .count = 0 ; // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'p' missing}}
630+ }
631+
632+ void missing_struct_nested_unrelated (cb_nested *c, cb_nested *d) {
633+ c->nested .p = nullptr ; // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'count' missing}}
634+ d->nested .count = 0 ; // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'p' missing}}
635+ }
636+
637+ struct missing_struct_test {
638+ cb cb_;
639+ cb_nested nested_;
640+
641+ void set_cb_missing_ptr (std::span<int > sp) {
642+ cb_.count = sp.size (); // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'p' missing}}
643+ }
644+
645+ void set_cb_missing_count (std::span<int > sp) {
646+ cb_.p = sp.data (); // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'count' missing}}
647+ }
648+
649+ void set_nested_missing_ptr (std::span<int > sp) {
650+ nested_.nested .count = sp.size (); // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'p' missing}}
651+ }
652+
653+ void set_missing_unrelated (std::span<int > sp) {
654+ cb_.p = sp.data (); // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'count' missing}}
655+ nested_.nested .count = sp.size (); // expected-warning{{bounds-attributed group requires assigning 'count, p', assignments to 'p' missing}}
656+ }
657+ };
658+
555659// Duplicated assignments
556660
557661void duplicated_ptr (int *__counted_by (count) p, int count) {
0 commit comments