[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Sema / attr-counted-by-or-null-struct-ptrs.c
blob708bb727ce09dad7ecce8d1c3dd4a988a2477f27
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s
4 #define __counted_by_or_null(f) __attribute__((counted_by_or_null(f)))
5 #define __counted_by(f) __attribute__((counted_by(f)))
7 struct size_unknown;
8 struct size_known {
9 int field;
12 typedef void(*fn_ptr_ty)(void);
14 //==============================================================================
15 // __counted_by_or_null on struct member pointer in decl attribute position
16 //==============================================================================
18 struct on_member_pointer_complete_ty {
19 int count;
20 struct size_known * buf __counted_by_or_null(count);
23 struct on_member_pointer_incomplete_ty {
24 int count;
25 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}}
26 struct size_unknown * buf __counted_by_or_null(count);
29 struct on_member_pointer_const_incomplete_ty {
30 int count;
31 // 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}}
32 const struct size_unknown * buf __counted_by_or_null(count);
35 struct on_member_pointer_void_ty {
36 int count;
37 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}}
38 void* buf __counted_by_or_null(count);
41 struct on_member_pointer_fn_ptr_ty {
42 int count;
43 // buffer of `count` function pointers is allowed
44 void (**fn_ptr)(void) __counted_by_or_null(count);
47 struct on_member_pointer_fn_ptr_ty_ptr_ty {
48 int count;
49 // buffer of `count` function pointers is allowed
50 fn_ptr_ty* fn_ptr __counted_by_or_null(count);
53 struct on_member_pointer_fn_ty {
54 int count;
55 // buffer of `count` functions is not allowed
56 // 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}}
57 void (*fn_ptr)(void) __counted_by_or_null(count);
60 struct on_member_pointer_fn_ptr_ty_ty {
61 int count;
62 // buffer of `count` functions is not allowed
63 // 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}}
64 fn_ptr_ty fn_ptr __counted_by_or_null(count);
67 struct has_unannotated_vla {
68 int count;
69 int buffer[];
72 struct on_member_pointer_struct_with_vla {
73 int count;
74 // 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}}
75 struct has_unannotated_vla* objects __counted_by_or_null(count);
78 struct has_annotated_vla {
79 int count;
80 int buffer[] __counted_by(count);
83 // Currently prevented because computing the size of `objects` at runtime would
84 // require an O(N) walk of `objects` to take into account the length of the VLA
85 // in each struct instance.
86 struct on_member_pointer_struct_with_annotated_vla {
87 int count;
88 // 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}}
89 struct has_annotated_vla* objects __counted_by_or_null(count);
92 struct on_pointer_anon_buf {
93 int count;
94 struct {
95 struct size_known *buf __counted_by_or_null(count);
99 struct on_pointer_anon_count {
100 struct {
101 int count;
103 struct size_known *buf __counted_by_or_null(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
112 struct on_member_pointer_complete_ty_ty_pos {
113 int count;
114 struct size_known *__counted_by_or_null(count) buf;
117 struct on_member_pointer_incomplete_ty_ty_pos {
118 int count;
119 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}}
120 struct size_unknown * __counted_by_or_null(count) buf;
123 struct on_member_pointer_const_incomplete_ty_ty_pos {
124 int count;
125 // 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}}
126 const struct size_unknown * __counted_by_or_null(count) buf;
129 struct on_member_pointer_void_ty_ty_pos {
130 int count;
131 // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'void' is an incomplete type}}
132 void *__counted_by_or_null(count) buf;
135 // -
137 struct on_member_pointer_fn_ptr_ty_pos {
138 int count;
139 // buffer of `count` function pointers is allowed
140 void (** __counted_by_or_null(count) fn_ptr)(void);
143 struct on_member_pointer_fn_ptr_ty_ptr_ty_pos {
144 int count;
145 // buffer of `count` function pointers is allowed
146 fn_ptr_ty* __counted_by_or_null(count) fn_ptr;
149 struct on_member_pointer_fn_ty_ty_pos {
150 int count;
151 // buffer of `count` functions is not allowed
152 // 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}}
153 void (* __counted_by_or_null(count) fn_ptr)(void);
156 struct on_member_pointer_fn_ptr_ty_ty_pos {
157 int count;
158 // buffer of `count` functions is not allowed
159 // 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}}
160 fn_ptr_ty __counted_by_or_null(count) fn_ptr;
163 // TODO: This should be forbidden but isn't due to counted_by_or_null being treated
164 // as a declaration attribute.
165 struct on_member_pointer_fn_ptr_ty_ty_pos_inner {
166 int count;
167 void (* __counted_by_or_null(count) * fn_ptr)(void);
170 struct on_member_pointer_struct_with_vla_ty_pos {
171 int count;
172 // 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}}
173 struct has_unannotated_vla *__counted_by_or_null(count) objects;
176 // Currently prevented because computing the size of `objects` at runtime would
177 // require an O(N) walk of `objects` to take into account the length of the VLA
178 // in each struct instance.
179 struct on_member_pointer_struct_with_annotated_vla_ty_pos {
180 int count;
181 // 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}}
182 struct has_annotated_vla* __counted_by_or_null(count) objects;
185 struct on_nested_pointer_inner {
186 // TODO: This should be disallowed because in the `-fbounds-safety` model
187 // `__counted_by_or_null` can only be nested when used in function parameters.
188 int count;
189 struct size_known *__counted_by_or_null(count) *buf;
192 struct on_nested_pointer_outer {
193 int count;
194 struct size_known **__counted_by_or_null(count) buf;
197 struct on_pointer_anon_buf_ty_pos {
198 int count;
199 struct {
200 struct size_known * __counted_by_or_null(count) buf;
204 struct on_pointer_anon_count_ty_pos {
205 struct {
206 int count;
208 struct size_known *__counted_by_or_null(count) buf;
211 //==============================================================================
212 // __counted_by_or_null on struct non-pointer members
213 //==============================================================================
215 struct on_pod_ty {
216 int count;
217 // expected-error-re@+1{{'counted_by_or_null' only applies to pointers{{$}}}}
218 int wrong_ty __counted_by_or_null(count);
221 struct on_void_ty {
222 int count;
223 // expected-error-re@+2{{'counted_by_or_null' only applies to pointers{{$}}}}
224 // expected-error@+1{{field has incomplete type 'void'}}
225 void wrong_ty __counted_by_or_null(count);