1 // RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s
3 #define __counted_by(f) __attribute__((counted_by(f)))
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
);
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}}
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
);
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}}
37 struct on_member_pointer_fn_ptr_ty
{
38 // buffer of `count` function pointers is allowed
39 void (**fn_ptr
)(void) __counted_by(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
);
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
);
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
);
64 struct has_unannotated_vla
{
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
);
75 struct has_annotated_vla
{
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
);
89 struct on_pointer_anon_buf
{
90 // TODO: Support referring to parent scope
92 // expected-error@+1{{use of undeclared identifier 'count'}}
93 struct size_known
*buf
__counted_by(count
);
98 struct on_pointer_anon_count
{
99 struct size_known
*buf
__counted_by(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
{
114 // expected-error@+1{{use of undeclared identifier 'count'}}
115 struct size_known
*__counted_by(count
) buf
;
119 struct on_member_pointer_incomplete_ty_ty_pos
{
121 // expected-error@+1{{use of undeclared identifier 'count'}}
122 struct size_unknown
* __counted_by(count
) buf
;
126 struct on_member_pointer_const_incomplete_ty_ty_pos
{
128 // expected-error@+1{{use of undeclared identifier 'count'}}
129 const struct size_unknown
* __counted_by(count
) buf
;
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
;
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);
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
;
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);
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);
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
;
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);
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
;
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
;
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
;
214 struct on_nested_pointer_outer
{
216 // expected-error@+1{{use of undeclared identifier 'count'}}
217 struct size_known
**__counted_by(count
) buf
;
221 struct on_pointer_anon_buf_ty_pos
{
223 // TODO: Support referring to parent scope
224 // expected-error@+1{{use of undeclared identifier 'count'}}
225 struct size_known
* __counted_by(count
) buf
;
230 struct on_pointer_anon_count_ty_pos
{
232 // expected-error@+1{{use of undeclared identifier 'count'}}
233 struct size_known
*__counted_by(count
) buf
;
239 //==============================================================================
240 // __counted_by on struct non-pointer members
241 //==============================================================================
244 // expected-error@+1{{'counted_by' only applies to pointers or C99 flexible array members}}
245 int wrong_ty
__counted_by(count
);
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
);