1 // RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s 2 3 #define __counted_by(f) __attribute__((counted_by(f))) 4 5 struct size_unknown; 6 struct size_known { 7 int field; 8 }; 9 10 typedef void(*fn_ptr_ty)(void); 11 12 //============================================================================== 13 // __counted_by on struct member pointer in decl attribute position 14 //============================================================================== 15 16 struct on_member_pointer_complete_ty { 17 struct size_known * buf __counted_by(count); 18 int count; 19 }; 20 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}} 23 int count; 24 }; 25 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); 29 int count; 30 }; 31 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}} 34 int count; 35 }; 36 37 struct on_member_pointer_fn_ptr_ty { 38 // buffer of `count` function pointers is allowed 39 void (**fn_ptr)(void) __counted_by(count); 40 int count; 41 }; 42 43 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); 47 int count; 48 }; 49 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); 54 int count; 55 }; 56 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); 61 int count; 62 }; 63 64 struct has_unannotated_vla { 65 int count; 66 int buffer[]; 67 }; 68 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); 72 int count; 73 }; 74 75 struct has_annotated_vla { 76 int count; 77 int buffer[] __counted_by(count); 78 }; 79 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); 86 int count; 87 }; 88 89 struct on_pointer_anon_buf { 90 // TODO: Support referring to parent scope 91 struct { 92 // expected-error@+1{{use of undeclared identifier 'count'}} 93 struct size_known *buf __counted_by(count); 94 }; 95 int count; 96 }; 97 98 struct on_pointer_anon_count { 99 struct size_known *buf __counted_by(count); 100 struct { 101 int count; 102 }; 103 }; 104 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. 111 112 struct on_member_pointer_complete_ty_ty_pos { 113 // TODO: Allow this 114 // expected-error@+1{{use of undeclared identifier 'count'}} 115 struct size_known *__counted_by(count) buf; 116 int count; 117 }; 118 119 struct on_member_pointer_incomplete_ty_ty_pos { 120 // TODO: Allow this 121 // expected-error@+1{{use of undeclared identifier 'count'}} 122 struct size_unknown * __counted_by(count) buf; 123 int count; 124 }; 125 126 struct on_member_pointer_const_incomplete_ty_ty_pos { 127 // TODO: Allow this 128 // expected-error@+1{{use of undeclared identifier 'count'}} 129 const struct size_unknown * __counted_by(count) buf; 130 int count; 131 }; 132 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; 138 int count; 139 }; 140 141 // - 142 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); 148 int count; 149 }; 150 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; 156 int count; 157 }; 158 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); 164 int count; 165 }; 166 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); 171 int count; 172 }; 173 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; 179 int count; 180 }; 181 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); 187 int count; 188 }; 189 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; 195 int count; 196 }; 197 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; 203 int count; 204 }; 205 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; 211 int count; 212 }; 213 214 struct on_nested_pointer_outer { 215 // TODO: Allow this 216 // expected-error@+1{{use of undeclared identifier 'count'}} 217 struct size_known **__counted_by(count) buf; 218 int count; 219 }; 220 221 struct on_pointer_anon_buf_ty_pos { 222 struct { 223 // TODO: Support referring to parent scope 224 // expected-error@+1{{use of undeclared identifier 'count'}} 225 struct size_known * __counted_by(count) buf; 226 }; 227 int count; 228 }; 229 230 struct on_pointer_anon_count_ty_pos { 231 // TODO: Allow this 232 // expected-error@+1{{use of undeclared identifier 'count'}} 233 struct size_known *__counted_by(count) buf; 234 struct { 235 int count; 236 }; 237 }; 238 239 //============================================================================== 240 // __counted_by on struct non-pointer members 241 //============================================================================== 242 243 struct on_pod_ty { 244 // expected-error@+1{{'counted_by' only applies to pointers or C99 flexible array members}} 245 int wrong_ty __counted_by(count); 246 int count; 247 }; 248 249 struct on_void_ty { 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); 253 int count; 254 }; 255