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)))
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
);
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}}
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
);
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}}
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
);
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
);
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
);
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
);
65 struct has_unannotated_vla
{
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
);
76 struct has_annotated_vla
{
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
);
90 struct on_pointer_anon_buf
{
91 // TODO: Support referring to parent scope
93 // expected-error@+1{{use of undeclared identifier 'count'}}
94 struct size_known
*buf
__counted_by_or_null(count
);
99 struct on_pointer_anon_count
{
100 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 and is **not** late parsed resulting in the `count`
111 // field being unavailable.
113 struct on_member_pointer_complete_ty_ty_pos
{
115 // expected-error@+1{{use of undeclared identifier 'count'}}
116 struct size_known
*__counted_by_or_null(count
) buf
;
120 struct on_member_pointer_incomplete_ty_ty_pos
{
122 // expected-error@+1{{use of undeclared identifier 'count'}}
123 struct size_unknown
* __counted_by_or_null(count
) buf
;
127 struct on_member_pointer_const_incomplete_ty_ty_pos
{
129 // expected-error@+1{{use of undeclared identifier 'count'}}
130 const struct size_unknown
* __counted_by_or_null(count
) buf
;
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
;
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);
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
;
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);
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);
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
;
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);
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
;
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
;
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
;
215 struct on_nested_pointer_outer
{
217 // expected-error@+1{{use of undeclared identifier 'count'}}
218 struct size_known
**__counted_by_or_null(count
) buf
;
222 struct on_pointer_anon_buf_ty_pos
{
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
;
231 struct on_pointer_anon_count_ty_pos
{
233 // expected-error@+1{{use of undeclared identifier 'count'}}
234 struct size_known
*__counted_by_or_null(count
) buf
;
240 //==============================================================================
241 // __counted_by_or_null on struct non-pointer members
242 //==============================================================================
245 // expected-error-re@+1{{'counted_by_or_null' only applies to pointers{{$}}}}
246 int wrong_ty
__counted_by_or_null(count
);
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
);