@@ -69,6 +69,148 @@ void good_struct_self_loop(cb *c) {
6969  }
7070}
7171
72+ //  Inout pointer and count
73+ 
74+ void  good_inout_span (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
75+   *p = sp.data ();
76+   *count = sp.size ();
77+ }
78+ 
79+ void  bad_inout_span (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
80+   *p = sp.data (); //  TODO-expected-warning{{unsafe assignment to count-attributed pointer}}
81+   *count = 42 ;
82+ }
83+ 
84+ void  good_inout_subspan_const (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
85+   *p = sp.first (42 ).data ();
86+   *count = 42 ;
87+ }
88+ 
89+ void  good_inout_subspan_var (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp, size_t new_count) {
90+   *p = sp.first (new_count).data ();
91+   *count = new_count;
92+ }
93+ 
94+ void  good_inout_subspan_complex (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp, size_t i, size_t j) {
95+   *p = sp.first (i + j * 2 ).data ();
96+   *count = i + j * 2 ;
97+ }
98+ 
99+ void  good_inout_span_if (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
100+   if  (p && count) {
101+     *p = sp.data ();
102+     *count = sp.size ();
103+   }
104+ }
105+ 
106+ void  bad_inout_span_if (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp, size_t size) {
107+   if  (p && count) {
108+     *p = sp.data (); //  TODO-expected-warning{{unsafe assignment to count-attributed pointer}}
109+     *count = size;
110+   }
111+ }
112+ 
113+ class  inout_class  {
114+   void  good_inout_span (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
115+     *p = sp.data ();
116+     *count = sp.size ();
117+   }
118+ 
119+   void  bad_inout_span (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
120+     *p = sp.data (); //  TODO-expected-warning{{unsafe assignment to count-attributed pointer}}
121+     *count = 42 ;
122+   }
123+ 
124+   void  good_inout_subspan_const (int  *__counted_by (*count) *p, size_t *count, std::span<int> sp) {
125+     *p = sp.first (42 ).data ();
126+     *count = 42 ;
127+   }
128+ };
129+ 
130+ //  Inout pointer
131+ 
132+ void  bad_inout_ptr_span (int  *__counted_by (count) *p, int count, std::span<int> sp) {
133+   *p = sp.data (); //  TODO-expected-warning{{unsafe assignment to count-attributed pointer}}
134+ }
135+ 
136+ void  good_inout_ptr_subspan (int  *__counted_by (count) *p, size_t count, std::span<int> sp) {
137+   *p = sp.first (count).data ();
138+ }
139+ 
140+ void  good_inout_ptr_const_subspan (int  *__counted_by (42 ) *p, std::span<int> sp) {
141+   *p = sp.first (42 ).data ();
142+ }
143+ 
144+ void  good_inout_ptr_multi_subspan (int  *__counted_by (a + b) *p, size_t a, size_t b, std::span<int> sp) {
145+   *p = sp.first (a + b).data ();
146+ }
147+ 
148+ class  inout_ptr_class  {
149+   void  bad_inout_ptr_span (int  *__counted_by (count) *p, int count, std::span<int> sp) {
150+     *p = sp.data (); //  TODO-expected-warning{{unsafe assignment to count-attributed pointer}}
151+   }
152+ 
153+   void  good_inout_ptr_subspan (int  *__counted_by (count) *p, size_t count, std::span<int> sp) {
154+     *p = sp.first (count).data ();
155+   }
156+ };
157+ 
158+ //  Immutable pointers/dependent values
159+ 
160+ void  immutable_ptr_to_ptr (int  *__counted_by (*count) *p, int *count) {
161+   p = nullptr ; //  expected-warning{{cannot assign to parameter 'p' because it points to a count-attributed pointer}}
162+   *count = 0 ;
163+ }
164+ 
165+ void  immutable_ptr_to_value (int  *__counted_by (*count) *p, int *count) {
166+   *p = nullptr ;
167+   count = nullptr ; //  expected-warning{{cannot assign to parameter 'count' because it points to a dependent count}}
168+ }
169+ 
170+ void  immutable_ptr_with_inout_value (int  *__counted_by (*count) p, int *count) {
171+   p = nullptr ; //  expected-warning{{cannot assign to parameter 'p' because its type depends on an inout dependent count}}
172+   *count = 0 ;
173+ }
174+ 
175+ void  immutable_ptr_with_inout_value2 (int  *__counted_by (*count) p, int *__counted_by(*count) *q, int *count) {
176+   p = nullptr ;  //  expected-warning{{cannot assign to parameter 'p' because its type depends on an inout dependent count}}
177+   *q = nullptr ;
178+   *count = 0 ;
179+ }
180+ 
181+ void  immutable_value_with_inout_ptr (int  *__counted_by (count) *p, int count) {
182+   *p = nullptr ;
183+   count = 0 ; //  expected-warning{{cannot assign to parameter 'count' because it's used as dependent count in an inout count-attributed pointer}}
184+ }
185+ 
186+ void  immutable_value_with_inout_ptr2 (int  *__counted_by (count) p, int *__counted_by(count) *q, int count) {
187+   p = nullptr ;
188+   *q = nullptr ;
189+   count = 0 ; //  expected-warning{{cannot assign to parameter 'count' because it's used as dependent count in an inout count-attributed pointer}}
190+ }
191+ 
192+ class  immutable_class  {
193+   void  immutable_ptr_to_ptr (int  *__counted_by (*count) *p, int *count) {
194+     p = nullptr ; //  expected-warning{{cannot assign to parameter 'p' because it points to a count-attributed pointer}}
195+     *count = 0 ;
196+   }
197+ 
198+   void  immutable_ptr_to_value (int  *__counted_by (*count) *p, int *count) {
199+     *p = nullptr ;
200+     count = nullptr ; //  expected-warning{{cannot assign to parameter 'count' because it points to a dependent count}}
201+   }
202+ 
203+   void  immutable_ptr_with_inout_value (int  *__counted_by (*count) p, int *count) {
204+     p = nullptr ; //  expected-warning{{cannot assign to parameter 'p' because its type depends on an inout dependent count}}
205+     *count = 0 ;
206+   }
207+ 
208+   void  immutable_value_with_inout_ptr (int  *__counted_by (count) *p, int count) {
209+     *p = nullptr ;
210+     count = 0 ; //  expected-warning{{cannot assign to parameter 'count' because it's used as dependent count in an inout count-attributed pointer}}
211+   }
212+ };
213+ 
72214//  Assigns to bounds-attributed that we consider too complex to analyze.
73215
74216void  too_complex_assign_to_ptr (int  *__counted_by (count) p, int count, int *q) {
0 commit comments