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)))
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
{
20 struct size_known
* buf
__counted_by_or_null(count
);
23 struct on_member_pointer_incomplete_ty
{
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
{
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
{
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
{
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
{
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
{
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
{
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
{
72 struct on_member_pointer_struct_with_vla
{
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
{
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
{
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
{
95 struct size_known
*buf
__counted_by_or_null(count
);
99 struct on_pointer_anon_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
{
114 struct size_known
*__counted_by_or_null(count
) buf
;
117 struct on_member_pointer_incomplete_ty_ty_pos
{
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
{
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
{
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
;
137 struct on_member_pointer_fn_ptr_ty_pos
{
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
{
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
{
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
{
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
{
167 void (* __counted_by_or_null(count
) * fn_ptr
)(void);
170 struct on_member_pointer_struct_with_vla_ty_pos
{
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
{
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.
189 struct size_known
*__counted_by_or_null(count
) *buf
;
192 struct on_nested_pointer_outer
{
194 struct size_known
**__counted_by_or_null(count
) buf
;
197 struct on_pointer_anon_buf_ty_pos
{
200 struct size_known
* __counted_by_or_null(count
) buf
;
204 struct on_pointer_anon_count_ty_pos
{
208 struct size_known
*__counted_by_or_null(count
) buf
;
211 //==============================================================================
212 // __counted_by_or_null on struct non-pointer members
213 //==============================================================================
217 // expected-error-re@+1{{'counted_by_or_null' only applies to pointers{{$}}}}
218 int wrong_ty
__counted_by_or_null(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
);