256 lines · c
1// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -Wpointer-arith -verify %s2 3#define __counted_by(f) __attribute__((counted_by(f)))4 5struct size_unknown;6struct size_known {7 int field;8};9 10typedef void(*fn_ptr_ty)(void);11 12//==============================================================================13// __counted_by on struct member pointer in decl attribute position14//==============================================================================15 16struct on_member_pointer_complete_ty {17 struct size_known * buf __counted_by(count);18 int count;19};20 21struct on_member_pointer_incomplete_ty {22 struct size_unknown * buf __counted_by(count); // ok23 int count;24};25 26struct on_member_pointer_const_incomplete_ty {27 const struct size_unknown * buf __counted_by(count); // ok28 int count;29};30 31struct on_member_pointer_void_ty {32 // expected-warning@+2{{'counted_by' on a pointer to void is a GNU extension, treated as 'sized_by'}}33 // expected-note@+1{{use '__sized_by' to suppress this warning}}34 void* buf __counted_by(count);35 int count;36};37 38struct on_member_pointer_fn_ptr_ty {39 // buffer of `count` function pointers is allowed40 void (**fn_ptr)(void) __counted_by(count);41 int count;42};43 44 45struct on_member_pointer_fn_ptr_ty_ptr_ty {46 // buffer of `count` function pointers is allowed47 fn_ptr_ty* fn_ptr __counted_by(count);48 int count;49};50 51struct on_member_pointer_fn_ty {52 // buffer of `count` functions is not allowed53 // expected-error@+1{{'counted_by' 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(count);55 int count;56};57 58struct on_member_pointer_fn_ptr_ty_ty {59 // buffer of `count` functions is not allowed60 // expected-error@+1{{'counted_by' 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(count);62 int count;63};64 65struct has_unannotated_vla {66 int count;67 int buffer[];68};69 70struct on_member_pointer_struct_with_vla {71 // 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}}72 struct has_unannotated_vla* objects __counted_by(count);73 int count;74};75 76struct has_annotated_vla {77 int count;78 int buffer[] __counted_by(count);79};80 81// Currently prevented because computing the size of `objects` at runtime would82// require an O(N) walk of `objects` to take into account the length of the VLA83// in each struct instance.84struct on_member_pointer_struct_with_annotated_vla {85 // 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}}86 struct has_annotated_vla* objects __counted_by(count);87 int count;88};89 90struct on_pointer_anon_buf {91 // TODO: Support referring to parent scope92 struct {93 // expected-error@+1{{use of undeclared identifier 'count'}}94 struct size_known *buf __counted_by(count);95 };96 int count;97};98 99struct on_pointer_anon_count {100 struct size_known *buf __counted_by(count);101 struct {102 int count;103 };104};105 106//==============================================================================107// __counted_by on struct member pointer in type attribute position108//==============================================================================109// TODO: Correctly parse counted_by as a type attribute. Currently it is parsed110// as a declaration attribute and is **not** late parsed resulting in the `count`111// field being unavailable.112 113struct on_member_pointer_complete_ty_ty_pos {114 // TODO: Allow this115 // expected-error@+1{{use of undeclared identifier 'count'}}116 struct size_known *__counted_by(count) buf;117 int count;118};119 120struct on_member_pointer_incomplete_ty_ty_pos {121 // TODO: Allow this122 // expected-error@+1{{use of undeclared identifier 'count'}}123 struct size_unknown * __counted_by(count) buf;124 int count;125};126 127struct on_member_pointer_const_incomplete_ty_ty_pos {128 // TODO: Allow this129 // expected-error@+1{{use of undeclared identifier 'count'}}130 const struct size_unknown * __counted_by(count) buf;131 int count;132};133 134struct on_member_pointer_void_ty_ty_pos {135 // TODO: This should fail because the attribute is136 // on a pointer with the pointee being an incomplete type.137 // expected-error@+1{{use of undeclared identifier 'count'}}138 void *__counted_by(count) buf;139 int count;140};141 142// -143 144struct on_member_pointer_fn_ptr_ty_pos {145 // TODO: buffer of `count` function pointers should be allowed146 // but fails because this isn't late parsed.147 // expected-error@+1{{use of undeclared identifier 'count'}}148 void (** __counted_by(count) fn_ptr)(void);149 int count;150};151 152struct on_member_pointer_fn_ptr_ty_ptr_ty_pos {153 // TODO: buffer of `count` function pointers should be allowed154 // but fails because this isn't late parsed.155 // expected-error@+1{{use of undeclared identifier 'count'}}156 fn_ptr_ty* __counted_by(count) fn_ptr;157 int count;158};159 160struct on_member_pointer_fn_ty_ty_pos {161 // TODO: This should fail because the attribute is162 // on a pointer with the pointee being a function type.163 // expected-error@+1{{use of undeclared identifier 'count'}}164 void (* __counted_by(count) fn_ptr)(void);165 int count;166};167 168struct on_member_pointer_fn_ptr_ty_ty_pos {169 // TODO: buffer of `count` function pointers should be allowed170 // expected-error@+1{{use of undeclared identifier 'count'}}171 void (** __counted_by(count) fn_ptr)(void);172 int count;173};174 175struct on_member_pointer_fn_ptr_ty_typedef_ty_pos {176 // TODO: This should fail because the attribute is177 // 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(count) fn_ptr;180 int count;181};182 183struct on_member_pointer_fn_ptr_ty_ty_pos_inner {184 // TODO: This should fail because the attribute is185 // on a pointer with the pointee being a function type.186 // expected-error@+1{{use of undeclared identifier 'count'}}187 void (* __counted_by(count) * fn_ptr)(void);188 int count;189};190 191struct on_member_pointer_struct_with_vla_ty_pos {192 // TODO: This should fail because the attribute is193 // 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(count) objects;196 int count;197};198 199struct on_member_pointer_struct_with_annotated_vla_ty_pos {200 // TODO: This should fail because the attribute is201 // 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(count) objects;204 int count;205};206 207struct on_nested_pointer_inner {208 // TODO: This should be disallowed because in the `-fbounds-safety` model209 // `__counted_by` can only be nested when used in function parameters.210 // expected-error@+1{{use of undeclared identifier 'count'}}211 struct size_known *__counted_by(count) *buf;212 int count;213};214 215struct on_nested_pointer_outer {216 // TODO: Allow this217 // expected-error@+1{{use of undeclared identifier 'count'}}218 struct size_known **__counted_by(count) buf;219 int count;220};221 222struct on_pointer_anon_buf_ty_pos {223 struct {224 // TODO: Support referring to parent scope225 // expected-error@+1{{use of undeclared identifier 'count'}}226 struct size_known * __counted_by(count) buf;227 };228 int count;229};230 231struct on_pointer_anon_count_ty_pos {232 // TODO: Allow this233 // expected-error@+1{{use of undeclared identifier 'count'}}234 struct size_known *__counted_by(count) buf;235 struct {236 int count;237 };238};239 240//==============================================================================241// __counted_by on struct non-pointer members242//==============================================================================243 244struct on_pod_ty {245 // expected-error@+1{{'counted_by' only applies to pointers or C99 flexible array members}}246 int wrong_ty __counted_by(count);247 int count;248};249 250struct on_void_ty {251 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}}252 // expected-error@+1{{field has incomplete type 'void'}}253 void wrong_ty __counted_by(count);254 int count;255};256