[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Sema / attr-counted-by-or-null-late-parsed-struct-ptrs.c
blob95f517e3144f72839dc19ec32e576124dc9415d2
1 // RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s
3 #define __counted_by_or_null(f) __attribute__((counted_by_or_null(f)))
4 #define __counted_by(f) __attribute__((counted_by(f)))
6 struct size_unknown;
7 struct size_known {
8 int field;
9 };
11 typedef void(*fn_ptr_ty)(void);
13 //==============================================================================
14 // __counted_by_or_null on struct member pointer in decl attribute position
15 //==============================================================================
17 struct on_member_pointer_complete_ty {
18 struct size_known * buf __counted_by_or_null(count);
19 int count;
22 struct on_member_pointer_incomplete_ty {
23 struct size_unknown * buf __counted_by_or_null(count); // expected-error{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}}
24 int count;
27 struct on_member_pointer_const_incomplete_ty {
28 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}}
29 const struct size_unknown * buf __counted_by_or_null(count);
30 int count;
33 struct on_member_pointer_void_ty {
34 void* buf __counted_by_or_null(count); // expected-error{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}}
35 int count;
38 struct on_member_pointer_fn_ptr_ty {
39 // buffer of `count` function pointers is allowed
40 void (**fn_ptr)(void) __counted_by_or_null(count);
41 int count;
45 struct on_member_pointer_fn_ptr_ty_ptr_ty {
46 // buffer of `count` function pointers is allowed
47 fn_ptr_ty* fn_ptr __counted_by_or_null(count);
48 int count;
51 struct on_member_pointer_fn_ty {
52 // buffer of `count` functions is not allowed
53 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}
54 void (*fn_ptr)(void) __counted_by_or_null(count);
55 int count;
58 struct on_member_pointer_fn_ptr_ty_ty {
59 // buffer of `count` functions is not allowed
60 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void (void)' is a function type}}
61 fn_ptr_ty fn_ptr __counted_by_or_null(count);
62 int count;
65 struct has_unannotated_vla {
66 int count;
67 int buffer[];
70 struct on_member_pointer_struct_with_vla {
71 // expected-error@+1{{'counted_by_or_null' 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}}
72 struct has_unannotated_vla* objects __counted_by_or_null(count);
73 int count;
76 struct has_annotated_vla {
77 int count;
78 int buffer[] __counted_by(count);
81 // Currently prevented because computing the size of `objects` at runtime would
82 // require an O(N) walk of `objects` to take into account the length of the VLA
83 // in each struct instance.
84 struct on_member_pointer_struct_with_annotated_vla {
85 // expected-error@+1{{'counted_by_or_null' 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}}
86 struct has_annotated_vla* objects __counted_by_or_null(count);
87 int count;
90 struct on_pointer_anon_buf {
91 // TODO: Support referring to parent scope
92 struct {
93 // expected-error@+1{{use of undeclared identifier 'count'}}
94 struct size_known *buf __counted_by_or_null(count);
96 int count;
99 struct on_pointer_anon_count {
100 struct size_known *buf __counted_by_or_null(count);
101 struct {
102 int count;
106 //==============================================================================
107 // __counted_by_or_null on struct member pointer in type attribute position
108 //==============================================================================
109 // TODO: Correctly parse counted_by_or_null as a type attribute. Currently it is parsed
110 // as a declaration attribute and is **not** late parsed resulting in the `count`
111 // field being unavailable.
113 struct on_member_pointer_complete_ty_ty_pos {
114 // TODO: Allow this
115 // expected-error@+1{{use of undeclared identifier 'count'}}
116 struct size_known *__counted_by_or_null(count) buf;
117 int count;
120 struct on_member_pointer_incomplete_ty_ty_pos {
121 // TODO: Allow this
122 // expected-error@+1{{use of undeclared identifier 'count'}}
123 struct size_unknown * __counted_by_or_null(count) buf;
124 int count;
127 struct on_member_pointer_const_incomplete_ty_ty_pos {
128 // TODO: Allow this
129 // expected-error@+1{{use of undeclared identifier 'count'}}
130 const struct size_unknown * __counted_by_or_null(count) buf;
131 int count;
134 struct on_member_pointer_void_ty_ty_pos {
135 // TODO: This should fail because the attribute is
136 // on a pointer with the pointee being an incomplete type.
137 // expected-error@+1{{use of undeclared identifier 'count'}}
138 void *__counted_by_or_null(count) buf;
139 int count;
142 // -
144 struct on_member_pointer_fn_ptr_ty_pos {
145 // TODO: buffer of `count` function pointers should be allowed
146 // but fails because this isn't late parsed.
147 // expected-error@+1{{use of undeclared identifier 'count'}}
148 void (** __counted_by_or_null(count) fn_ptr)(void);
149 int count;
152 struct on_member_pointer_fn_ptr_ty_ptr_ty_pos {
153 // TODO: buffer of `count` function pointers should be allowed
154 // but fails because this isn't late parsed.
155 // expected-error@+1{{use of undeclared identifier 'count'}}
156 fn_ptr_ty* __counted_by_or_null(count) fn_ptr;
157 int count;
160 struct on_member_pointer_fn_ty_ty_pos {
161 // TODO: This should fail because the attribute is
162 // on a pointer with the pointee being a function type.
163 // expected-error@+1{{use of undeclared identifier 'count'}}
164 void (* __counted_by_or_null(count) fn_ptr)(void);
165 int count;
168 struct on_member_pointer_fn_ptr_ty_ty_pos {
169 // TODO: buffer of `count` function pointers should be allowed
170 // expected-error@+1{{use of undeclared identifier 'count'}}
171 void (** __counted_by_or_null(count) fn_ptr)(void);
172 int count;
175 struct on_member_pointer_fn_ptr_ty_typedef_ty_pos {
176 // TODO: This should fail because the attribute is
177 // on a pointer with the pointee being a function type.
178 // expected-error@+1{{use of undeclared identifier 'count'}}
179 fn_ptr_ty __counted_by_or_null(count) fn_ptr;
180 int count;
183 struct on_member_pointer_fn_ptr_ty_ty_pos_inner {
184 // TODO: This should fail because the attribute is
185 // on a pointer with the pointee being a function type.
186 // expected-error@+1{{use of undeclared identifier 'count'}}
187 void (* __counted_by_or_null(count) * fn_ptr)(void);
188 int count;
191 struct on_member_pointer_struct_with_vla_ty_pos {
192 // TODO: This should fail because the attribute is
193 // on a pointer with the pointee being a struct type with a VLA.
194 // expected-error@+1{{use of undeclared identifier 'count'}}
195 struct has_unannotated_vla *__counted_by_or_null(count) objects;
196 int count;
199 struct on_member_pointer_struct_with_annotated_vla_ty_pos {
200 // TODO: This should fail because the attribute is
201 // on a pointer with the pointee being a struct type with a VLA.
202 // expected-error@+1{{use of undeclared identifier 'count'}}
203 struct has_annotated_vla* __counted_by_or_null(count) objects;
204 int count;
207 struct on_nested_pointer_inner {
208 // TODO: This should be disallowed because in the `-fbounds-safety` model
209 // `__counted_by_or_null` can only be nested when used in function parameters.
210 // expected-error@+1{{use of undeclared identifier 'count'}}
211 struct size_known *__counted_by_or_null(count) *buf;
212 int count;
215 struct on_nested_pointer_outer {
216 // TODO: Allow this
217 // expected-error@+1{{use of undeclared identifier 'count'}}
218 struct size_known **__counted_by_or_null(count) buf;
219 int count;
222 struct on_pointer_anon_buf_ty_pos {
223 struct {
224 // TODO: Support referring to parent scope
225 // expected-error@+1{{use of undeclared identifier 'count'}}
226 struct size_known * __counted_by_or_null(count) buf;
228 int count;
231 struct on_pointer_anon_count_ty_pos {
232 // TODO: Allow this
233 // expected-error@+1{{use of undeclared identifier 'count'}}
234 struct size_known *__counted_by_or_null(count) buf;
235 struct {
236 int count;
240 //==============================================================================
241 // __counted_by_or_null on struct non-pointer members
242 //==============================================================================
244 struct on_pod_ty {
245 // expected-error-re@+1{{'counted_by_or_null' only applies to pointers{{$}}}}
246 int wrong_ty __counted_by_or_null(count);
247 int count;
250 struct on_void_ty {
251 // expected-error-re@+2{{'counted_by_or_null' only applies to pointers{{$}}}}
252 // expected-error@+1{{field has incomplete type 'void'}}
253 void wrong_ty __counted_by_or_null(count);
254 int count;