[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Sema / attr-counted-by-late-parsed-struct-ptrs.c
blob9ff3b080f6576b2ac850367c143fea0269b63764
1 // RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s
3 #define __counted_by(f) __attribute__((counted_by(f)))
5 struct size_unknown;
6 struct size_known {
7 int field;
8 };
10 typedef void(*fn_ptr_ty)(void);
12 //==============================================================================
13 // __counted_by on struct member pointer in decl attribute position
14 //==============================================================================
16 struct on_member_pointer_complete_ty {
17 struct size_known * buf __counted_by(count);
18 int count;
21 struct on_member_pointer_incomplete_ty {
22 struct size_unknown * buf __counted_by(count); // expected-error{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}}
23 int count;
26 struct on_member_pointer_const_incomplete_ty {
27 // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}}
28 const struct size_unknown * buf __counted_by(count);
29 int count;
32 struct on_member_pointer_void_ty {
33 void* buf __counted_by(count); // expected-error{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}}
34 int count;
37 struct on_member_pointer_fn_ptr_ty {
38 // buffer of `count` function pointers is allowed
39 void (**fn_ptr)(void) __counted_by(count);
40 int count;
44 struct on_member_pointer_fn_ptr_ty_ptr_ty {
45 // buffer of `count` function pointers is allowed
46 fn_ptr_ty* fn_ptr __counted_by(count);
47 int count;
50 struct on_member_pointer_fn_ty {
51 // buffer of `count` functions is not allowed
52 // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}
53 void (*fn_ptr)(void) __counted_by(count);
54 int count;
57 struct on_member_pointer_fn_ptr_ty_ty {
58 // buffer of `count` functions is not allowed
59 // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}
60 fn_ptr_ty fn_ptr __counted_by(count);
61 int count;
64 struct has_unannotated_vla {
65 int count;
66 int buffer[];
69 struct on_member_pointer_struct_with_vla {
70 // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_unannotated_vla' is a struct type with a flexible array member}}
71 struct has_unannotated_vla* objects __counted_by(count);
72 int count;
75 struct has_annotated_vla {
76 int count;
77 int buffer[] __counted_by(count);
80 // Currently prevented because computing the size of `objects` at runtime would
81 // require an O(N) walk of `objects` to take into account the length of the VLA
82 // in each struct instance.
83 struct on_member_pointer_struct_with_annotated_vla {
84 // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct has_annotated_vla' is a struct type with a flexible array member}}
85 struct has_annotated_vla* objects __counted_by(count);
86 int count;
89 struct on_pointer_anon_buf {
90 // TODO: Support referring to parent scope
91 struct {
92 // expected-error@+1{{use of undeclared identifier 'count'}}
93 struct size_known *buf __counted_by(count);
95 int count;
98 struct on_pointer_anon_count {
99 struct size_known *buf __counted_by(count);
100 struct {
101 int count;
105 //==============================================================================
106 // __counted_by on struct member pointer in type attribute position
107 //==============================================================================
108 // TODO: Correctly parse counted_by as a type attribute. Currently it is parsed
109 // as a declaration attribute and is **not** late parsed resulting in the `count`
110 // field being unavailable.
112 struct on_member_pointer_complete_ty_ty_pos {
113 // TODO: Allow this
114 // expected-error@+1{{use of undeclared identifier 'count'}}
115 struct size_known *__counted_by(count) buf;
116 int count;
119 struct on_member_pointer_incomplete_ty_ty_pos {
120 // TODO: Allow this
121 // expected-error@+1{{use of undeclared identifier 'count'}}
122 struct size_unknown * __counted_by(count) buf;
123 int count;
126 struct on_member_pointer_const_incomplete_ty_ty_pos {
127 // TODO: Allow this
128 // expected-error@+1{{use of undeclared identifier 'count'}}
129 const struct size_unknown * __counted_by(count) buf;
130 int count;
133 struct on_member_pointer_void_ty_ty_pos {
134 // TODO: This should fail because the attribute is
135 // on a pointer with the pointee being an incomplete type.
136 // expected-error@+1{{use of undeclared identifier 'count'}}
137 void *__counted_by(count) buf;
138 int count;
141 // -
143 struct on_member_pointer_fn_ptr_ty_pos {
144 // TODO: buffer of `count` function pointers should be allowed
145 // but fails because this isn't late parsed.
146 // expected-error@+1{{use of undeclared identifier 'count'}}
147 void (** __counted_by(count) fn_ptr)(void);
148 int count;
151 struct on_member_pointer_fn_ptr_ty_ptr_ty_pos {
152 // TODO: buffer of `count` function pointers should be allowed
153 // but fails because this isn't late parsed.
154 // expected-error@+1{{use of undeclared identifier 'count'}}
155 fn_ptr_ty* __counted_by(count) fn_ptr;
156 int count;
159 struct on_member_pointer_fn_ty_ty_pos {
160 // TODO: This should fail because the attribute is
161 // on a pointer with the pointee being a function type.
162 // expected-error@+1{{use of undeclared identifier 'count'}}
163 void (* __counted_by(count) fn_ptr)(void);
164 int count;
167 struct on_member_pointer_fn_ptr_ty_ty_pos {
168 // TODO: buffer of `count` function pointers should be allowed
169 // expected-error@+1{{use of undeclared identifier 'count'}}
170 void (** __counted_by(count) fn_ptr)(void);
171 int count;
174 struct on_member_pointer_fn_ptr_ty_typedef_ty_pos {
175 // TODO: This should fail because the attribute is
176 // on a pointer with the pointee being a function type.
177 // expected-error@+1{{use of undeclared identifier 'count'}}
178 fn_ptr_ty __counted_by(count) fn_ptr;
179 int count;
182 struct on_member_pointer_fn_ptr_ty_ty_pos_inner {
183 // TODO: This should fail because the attribute is
184 // on a pointer with the pointee being a function type.
185 // expected-error@+1{{use of undeclared identifier 'count'}}
186 void (* __counted_by(count) * fn_ptr)(void);
187 int count;
190 struct on_member_pointer_struct_with_vla_ty_pos {
191 // TODO: This should fail because the attribute is
192 // on a pointer with the pointee being a struct type with a VLA.
193 // expected-error@+1{{use of undeclared identifier 'count'}}
194 struct has_unannotated_vla *__counted_by(count) objects;
195 int count;
198 struct on_member_pointer_struct_with_annotated_vla_ty_pos {
199 // TODO: This should fail because the attribute is
200 // on a pointer with the pointee being a struct type with a VLA.
201 // expected-error@+1{{use of undeclared identifier 'count'}}
202 struct has_annotated_vla* __counted_by(count) objects;
203 int count;
206 struct on_nested_pointer_inner {
207 // TODO: This should be disallowed because in the `-fbounds-safety` model
208 // `__counted_by` can only be nested when used in function parameters.
209 // expected-error@+1{{use of undeclared identifier 'count'}}
210 struct size_known *__counted_by(count) *buf;
211 int count;
214 struct on_nested_pointer_outer {
215 // TODO: Allow this
216 // expected-error@+1{{use of undeclared identifier 'count'}}
217 struct size_known **__counted_by(count) buf;
218 int count;
221 struct on_pointer_anon_buf_ty_pos {
222 struct {
223 // TODO: Support referring to parent scope
224 // expected-error@+1{{use of undeclared identifier 'count'}}
225 struct size_known * __counted_by(count) buf;
227 int count;
230 struct on_pointer_anon_count_ty_pos {
231 // TODO: Allow this
232 // expected-error@+1{{use of undeclared identifier 'count'}}
233 struct size_known *__counted_by(count) buf;
234 struct {
235 int count;
239 //==============================================================================
240 // __counted_by on struct non-pointer members
241 //==============================================================================
243 struct on_pod_ty {
244 // expected-error@+1{{'counted_by' only applies to pointers or C99 flexible array members}}
245 int wrong_ty __counted_by(count);
246 int count;
249 struct on_void_ty {
250 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}}
251 // expected-error@+1{{field has incomplete type 'void'}}
252 void wrong_ty __counted_by(count);
253 int count;