631 lines · c
1// RUN: %clang_cc1 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s3 4#define __counted_by(f) __attribute__((counted_by(f)))5 6// =============================================================================7// # Struct incomplete type with attribute in the decl position8// =============================================================================9 10// Note: This could be considered misleading. The typedef isn't actually on this11// line. Also note the discrepancy in diagnostic count (27 vs 51) is due to12// the pointer arithmetic on incomplete pointee type diagnostic always using13// diagnostic text that refers to the underlying forward decl, even when the14// typedef is used.15// expected-note@+3 27{{consider providing a complete definition for 'Incomplete_t' (aka 'struct IncompleteTy')}}16// The 'forward declaration' notes come from 'arithmetic on a pointer to an incomplete type' errors17// expected-note@+1 24{{forward declaration of 'struct IncompleteTy'}}18struct IncompleteTy; // expected-note 27{{consider providing a complete definition for 'struct IncompleteTy'}}19 20typedef struct IncompleteTy Incomplete_t; 21 22struct CBBufDeclPos {23 int count;24 struct IncompleteTy* buf __counted_by(count); // OK expected-note 27{{consider using '__sized_by' instead of '__counted_by'}}25 Incomplete_t* buf_typedef __counted_by(count); // OK expected-note 27{{consider using '__sized_by' instead of '__counted_by'}}26};27 28void consume_struct_IncompleteTy(struct IncompleteTy* buf);29 30int idx(void);31 32 33 34void test_CBBufDeclPos(struct CBBufDeclPos* ptr) {35 // ===========================================================================36 // ## Local variable initialization37 // ===========================================================================38 struct CBBufDeclPos explicit_desig_init = {39 .count = 0,40 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}41 .buf = 0x0,42 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}43 .buf_typedef = 0x044 };45 // Variable is not currently marked as invalid so uses of the variable allows46 // diagnostics to fire.47 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}48 explicit_desig_init.buf = 0x0;49 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}50 explicit_desig_init.buf_typedef = 0x0;51 // expected-error@+1{{cannot use 'explicit_desig_init.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}52 void *tmp = explicit_desig_init.buf;53 // expected-error@+1{{cannot use 'explicit_desig_init.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}54 void *tmp2 = explicit_desig_init.buf_typedef;55 56 struct CBBufDeclPos partial_explicit_desig_init = {57 .count = 0,58 // .buf and .buf_typedef are implicit zero initialized59 // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}60 // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}61 };62 63 struct CBBufDeclPos implicit_full_init = {64 065 // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}66 // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}67 };68 // Variable is not currently marked as invalid so uses of the variable allows69 // diagnostics to fire.70 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}71 implicit_full_init.buf = 0x0;72 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}73 implicit_full_init.buf_typedef = 0x0;74 // expected-error@+1{{cannot use 'implicit_full_init.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}75 void* tmp3 = implicit_full_init.buf;76 // expected-error@+1{{cannot use 'implicit_full_init.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}77 void* tmp4 = implicit_full_init.buf_typedef;78 79 struct CBBufDeclPos explicit_non_desig_init = {80 0,81 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}82 0x0,83 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}84 0x085 };86 87 88 89 90 // ===========================================================================91 // ## Assignment to fields92 // ===========================================================================93 struct CBBufDeclPos uninit;94 uninit.count = 0;95 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}96 uninit.buf = 0x0;97 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}98 uninit.buf_typedef = 0x0;99 ptr->count = 0;100 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}101 ptr->buf = 0x0;102 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}103 ptr->buf_typedef = 0x0;104 105 106 // ===========================================================================107 // ## Make sure modifying the fields through other assignment operators is not108 // allowed109 // ===========================================================================110 uninit.buf++; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}111 ++uninit.buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}112 uninit.buf += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}113 uninit.buf_typedef++; // // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}114 ++uninit.buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}115 uninit.buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}116 117 uninit.buf--; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}118 --uninit.buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}119 uninit.buf -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}120 uninit.buf_typedef--; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}121 --uninit.buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}122 uninit.buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}123 124 ptr->buf++; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}125 ++ptr->buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}126 ptr->buf += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}127 ptr->buf--; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}128 --ptr->buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}129 ptr->buf -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}}130 131 ptr->buf_typedef++; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}132 ++ptr->buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}133 ptr->buf_typedef += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}134 ptr->buf_typedef--; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}135 --ptr->buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}136 ptr->buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}}137 138 // ===========================================================================139 // ## Use of fields in expressions140 // ===========================================================================141 // expected-error@+2{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}142 void* addr = 143 ((char*) uninit.buf ) + 1;144 // expected-error@+2{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}145 void* addr_typedef = 146 ((char*) uninit.buf_typedef ) + 1;147 // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}148 void* addr_ptr = 149 ((char*) ptr->buf ) + 1;150 // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}151 void* addr_ptr_typedef = 152 ((char*) ptr->buf_typedef ) + 1;153 154 155 // ===========================================================================156 // ## Take address of fields157 // ===========================================================================158 // TODO: This should be forbidden, not because of the incomplete pointee type159 // but because in the -fbounds-safety language model the address of a160 // `counted_by` pointer cannot be taken to avoid it being possible to modify161 // the `counted_by` pointer through another pointer. Whether or not this162 // should be forbidden when `-fbounds-safety` is off is TBD.163 //164 // The incomplete pointee type isn't actually a problem here for165 // `-fbounds-safety` because taking the address of a pointer returns a pointer166 // that have the bounds of a single `void*`, so bounds checks on the resulting167 // pointer don't need to know `sizeof(struct IncompleteTy)` but instead168 // `sizeof(struct IncompleteTy* buf __counted_by(count))` which is just the169 // size of a pointer.170 void* take_addr = &uninit.buf;171 void* take_addr_typedef = &uninit.buf_typedef;172 void* take_addr_ptr = &ptr->buf;173 void* take_addr_ptr_typedef = &ptr->buf_typedef;174 175 // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}176 struct IncompleteTy* addr_elt_zero = &uninit.buf[0];177 // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}178 struct IncompleteTy* addr_elt_idx = &uninit.buf[idx()];179 180 // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}181 struct IncompleteTy* addr_elt_zero_typedef = &uninit.buf_typedef[0];182 // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}183 struct IncompleteTy* addr_elt_idx_typedef = &uninit.buf_typedef[idx()];184 185 // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}186 struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0];187 // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}188 struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()];189 // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}190 struct IncompleteTy* addr_elt_zero_ptr_typedef = &ptr->buf_typedef[0];191 // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}192 struct IncompleteTy* addr_elt_idx_ptr_typedef = &ptr->buf_typedef[idx()];193 194 195 // ===========================================================================196 // ## Use fields as call arguments197 // ===========================================================================198 // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}199 consume_struct_IncompleteTy(uninit.buf);200 // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}201 consume_struct_IncompleteTy(uninit.buf_typedef);202 // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}203 consume_struct_IncompleteTy(ptr->buf);204 // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}205 consume_struct_IncompleteTy(ptr->buf_typedef);206 207 // ===========================================================================208 // ## Use [] operator on fields209 // ===========================================================================210 // expected-error@+1 2{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}211 uninit.buf[0] = uninit.buf[1];212 // expected-error@+1 2{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}213 uninit.buf_typedef[0] = uninit.buf_typedef[1];214 // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}215 ptr->buf[0] = ptr->buf[1];216 // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}217 ptr->buf_typedef[0] = ptr->buf_typedef[1];218}219 220 221// =============================================================================222// ## Global initialization223// =============================================================================224 225struct CBBufDeclPos global_explicit_desig_init = {226 .count = 0,227 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}228 .buf = 0x0,229 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}230 .buf_typedef = 0x0231};232 233void use_global_explicit_desig_init(void) {234 // Variable isn't marked as invalid so diagnostics still fire235 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}236 global_explicit_desig_init.buf = 0x0;237 // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}238 global_explicit_desig_init.buf_typedef = 0x0;239}240 241struct CBBufDeclPos global_partial_explicit_desig_init = {242 .count = 0,243 // .buf and .buf_typedef are implicit zero initialized244 // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}245 // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}246};247 248struct CBBufDeclPos global_implicit_full_init = {249 0250 // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}251 // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}252};253 254struct CBBufDeclPos global_explicit_non_desig_init = {255 0,256 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}}257 0x0,258 // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}}259 0x0260};261 262extern struct CBBufDeclPos global_declaration; // OK263 264// TODO: These tentative definitions are implicitly empty initialized to zero.265// This should generate an error diagnostic but currently doesn't. There should266// be a carve out to allow `__counted_by(0)` which is the only constant count267// version of the attribute where it is valid to assign NULL.268struct CBBufDeclPos global_tentative_defn;269static struct CBBufDeclPos global_tentative_defn2;270 271// =============================================================================272// ## Completing the definition of the type allows use of CBBufDeclPos fields273// =============================================================================274struct IncompleteTy {275 int field;276};277 278void test_CBBufDeclPos_completed(struct CBBufDeclPos* ptr) {279 // Initialization is ok280 struct CBBufDeclPos explicit_desig_init = {281 .count = 0,282 .buf = 0x0,283 .buf_typedef = 0x0284 };285 286 struct CBBufDeclPos partial_explicit_desig_init = {287 .count = 0,288 // .buf and .buf_typedef are implicit zero initialized289 };290 291 struct CBBufDeclPos implicit_full_init = {0};292 293 struct CBBufDeclPos explicit_non_desig_init = {294 0,295 0x0,296 0x0297 };298 299 // Assignment to fields is ok300 ptr->buf = 0x0;301 ptr->buf_typedef = 0x0;302 303 // Use of fields in expressions is ok304 void* tmp = ptr->buf;305 void* tmp2 = ptr->buf_typedef;306 307 // Take address of fields is ok308 void* take_addr_ptr = &ptr->buf;309 void* take_addr_ptr_typedef = &ptr->buf_typedef;310 311 struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0];312 struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()];313 struct IncompleteTy* addr_elt_zero_ptr_typedef = &ptr->buf_typedef[0];314 struct IncompleteTy* addr_elt_idx_ptr_typedef = &ptr->buf_typedef[idx()];315 316 // As call arguments is ok317 consume_struct_IncompleteTy(ptr->buf);318 consume_struct_IncompleteTy(ptr->buf_typedef);319 320 // In [] operator is ok321 ptr->buf[0] = ptr->buf[1];322 ptr->buf_typedef[0] = ptr->buf_typedef[1];323}324 325// Global initialization is ok326 327struct CBBufDeclPos global_explicit_desig_init_completed = {328 .count = 0,329 .buf = 0x0,330 .buf_typedef = 0x0331};332 333struct CBBufDeclPos global_partial_explicit_desig_init_completed = {334 .count = 0,335 // .buf and .buf_typedef are implicit zero initialized336};337 338struct CBBufDeclPos global_implicit_full_init_completed = {0};339 340struct CBBufDeclPos global_explicit_non_desig_init_completed = {341 0,342 0x0,343 0x0344};345 346extern struct CBBufDeclPos global_declaration;347struct CBBufDeclPos global_tentative_defn;348static struct CBBufDeclPos global_tentative_defn2;349 350// =============================================================================351// # Struct incomplete type with attribute in the pointer position352// =============================================================================353 354// expected-note@+1 8{{consider providing a complete definition for 'Incomplete_ty2' (aka 'struct IncompleteTy2')}}355struct IncompleteTy2; // expected-note 8{{consider providing a complete definition for 'struct IncompleteTy2'}}356typedef struct IncompleteTy2 Incomplete_ty2;357 358void consume_struct_IncompleteTy2(struct IncompleteTy2* buf);359 360struct CBBufTyPos {361 int count;362 struct IncompleteTy2* __counted_by(count) buf ; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}}363 Incomplete_ty2 *__counted_by(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}}364};365 366void use_CBBufTyPos(struct CBBufTyPos* ptr) {367 struct CBBufTyPos explicit_desig_init = {368 .count = 0,369 // expected-error@+1{{cannot initialize 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}370 .buf = 0x0,371 // expected-error@+1{{cannot initialize 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}372 .buf_typedef = 0x0373 };374 375 // Assignment376 // expected-error@+1{{cannot assign to 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}377 explicit_desig_init.buf = 0x0;378 // expected-error@+1{{cannot assign to 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}379 explicit_desig_init.buf_typedef = 0x0;380 // expected-error@+1{{cannot assign to 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}381 ptr->buf = 0x0;382 // expected-error@+1{{cannot assign to 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}383 ptr->buf_typedef = 0x0;384 385 // Use386 // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}387 void* addr = 388 ((char*) ptr->buf ) + 1;389 // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}390 void* addr_typedef = 391 ((char*) ptr->buf_typedef ) + 1;392 393 // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}394 consume_struct_IncompleteTy2(ptr->buf);395 // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}396 consume_struct_IncompleteTy2(ptr->buf_typedef);397 398 // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}399 ptr->buf[0] = ptr->buf[1];400 // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}401 ptr->buf_typedef[0] = ptr->buf_typedef[1];402}403 404struct CBBufTyPos global_explicit_desig_init_struct_type_pos = {405 .count = 0,406 // expected-error@+1{{cannot initialize 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}}407 .buf = 0x0,408 // expected-error@+1{{cannot initialize 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}}409 .buf_typedef = 0x0410};411 412// Defining the type makes `CBBufTyPos` fields usable413struct IncompleteTy2 {414 int field;415};416 417void use_CBBufTyPos_completed(struct CBBufTyPos* ptr) {418 ptr->buf = 0x0;419 ptr->buf_typedef = 0x0;420 void* addr = ((char*) ptr->buf) + 1;421 void* addr_typedef = ((char*) ptr->buf_typedef) + 1;422}423 424// =============================================================================425// # union incomplete type426// =============================================================================427 428// expected-note@+1 8{{consider providing a complete definition for 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy')}}429union IncompleteUnionTy; // expected-note 8{{consider providing a complete definition for 'union IncompleteUnionTy'}}430typedef union IncompleteUnionTy IncompleteUnion_ty;431 432void consume_struct_IncompleteUnionTy(union IncompleteUnionTy* buf);433 434struct CBBufUnionTyPos {435 int count;436 union IncompleteUnionTy* __counted_by(count) buf ; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}}437 IncompleteUnion_ty *__counted_by(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}}438};439 440void use_CBBufUnionTyPos(struct CBBufUnionTyPos* ptr) {441 struct CBBufUnionTyPos explicit_desig_init = {442 .count = 0,443 // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}444 .buf = 0x0,445 // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}446 .buf_typedef = 0x0447 };448 449 // Assignment450 // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}451 explicit_desig_init.buf = 0x0;452 // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}453 explicit_desig_init.buf_typedef = 0x0;454 // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}455 ptr->buf = 0x0;456 // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}457 ptr->buf_typedef = 0x0;458 459 // Use460 // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}461 void* addr = 462 ((char*) ptr->buf ) + 1;463 // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}464 void* addr_typedef = 465 ((char*) ptr->buf_typedef ) + 1;466 467 // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}468 consume_struct_IncompleteUnionTy(ptr->buf);469 // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}470 consume_struct_IncompleteUnionTy(ptr->buf_typedef);471 472 // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}473 ptr->buf[0] = ptr->buf[1];474 // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}475 ptr->buf_typedef[0] = ptr->buf_typedef[1];476}477 478struct CBBufUnionTyPos global_explicit_desig_init_union_type_pos = {479 .count = 0,480 // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}}481 .buf = 0x0,482 // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}}483 .buf_typedef = 0x0484};485 486// Defining the type makes `CBBufUnionTyPos` fields usable487union IncompleteUnionTy {488 int field;489};490 491void use_CBBufUnionTyPos_completed(struct CBBufUnionTyPos* ptr) {492 ptr->buf = 0x0;493 ptr->buf_typedef = 0x0;494 void* addr = ((char*) ptr->buf) + 1;495 void* addr_typedef = ((char*) ptr->buf_typedef) + 1;496}497 498// =============================================================================499// # enum incomplete type500// =============================================================================501 502// expected-note@+1 8{{consider providing a complete definition for 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy')}}503enum IncompleteEnumTy; // expected-note 8{{consider providing a complete definition for 'enum IncompleteEnumTy'}}504typedef enum IncompleteEnumTy IncompleteEnum_ty;505 506void consume_struct_IncompleteEnumTy(enum IncompleteEnumTy* buf);507 508struct CBBufEnumTyPos {509 int count;510 enum IncompleteEnumTy* __counted_by(count) buf ; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}}511 IncompleteEnum_ty *__counted_by(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}}512};513 514void use_CBBufEnumTyPos(struct CBBufEnumTyPos* ptr) {515 struct CBBufEnumTyPos explicit_desig_init = {516 .count = 0,517 // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}518 .buf = 0x0,519 // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}520 .buf_typedef = 0x0521 };522 523 // Assignment524 // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}525 explicit_desig_init.buf = 0x0;526 // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}527 explicit_desig_init.buf_typedef = 0x0;528 // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}529 ptr->buf = 0x0;530 // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}531 ptr->buf_typedef = 0x0;532 533 // Use534 // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}535 void* addr = 536 ((char*) ptr->buf ) + 1;537 // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}538 void* addr_typedef = 539 ((char*) ptr->buf_typedef ) + 1;540 541 // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}542 consume_struct_IncompleteEnumTy(ptr->buf);543 // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}544 consume_struct_IncompleteEnumTy(ptr->buf_typedef);545 546 // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}547 ptr->buf[0] = ptr->buf[1];548 // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}549 ptr->buf_typedef[0] = ptr->buf_typedef[1];550}551 552struct CBBufEnumTyPos global_explicit_desig_init_enum_type_pos = {553 .count = 0,554 // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}}555 .buf = 0x0,556 // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}}557 .buf_typedef = 0x0558};559 560// Defining the type makes `CBBufEnumTyPos` fields usable561enum IncompleteEnumTy {562 ONE,563 TWO564};565 566void use_CBBufEnumTyPos_completed(struct CBBufEnumTyPos* ptr) {567 ptr->buf = 0x0;568 ptr->buf_typedef = 0x0;569 void* addr = ((char*) ptr->buf) + 1;570 void* addr_typedef = ((char*) ptr->buf_typedef) + 1;571}572 573// Make a complete enum by providing an underlying type574enum CompleteEnumTy : unsigned;575typedef enum CompleteEnumTy CompleteEnum_ty;576struct CBBufEnumTyPos2 {577 int count;578 enum CompleteEnumTy* __counted_by(count) buf;579 CompleteEnum_ty *__counted_by(count) buf_typedef;580};581 582void use_CBBufEnumTyPos2(struct CBBufEnumTyPos2* ptr) {583 struct CBBufEnumTyPos2 explicit_desig_init = {584 .count = 0,585 .buf = 0x0, // OK586 .buf_typedef = 0x0 // OK587 };588}589 590// Make a complete enum by providing a concrete declaration591enum CompleteEnumTy2 {592 VALUE_ONE,593 VALUE_TWO594};595typedef enum CompleteEnumTy2 CompleteEnum_ty2;596struct CBBufEnumTyPos3 {597 int count;598 enum CompleteEnumTy2* __counted_by(count) buf;599 CompleteEnum_ty2 *__counted_by(count) buf_typedef;600};601 602void use_CBBufEnumTyPos3(struct CBBufEnumTyPos3* ptr) {603 struct CBBufEnumTyPos3 explicit_desig_init = {604 .count = 0,605 .buf = 0x0, // OK606 .buf_typedef = 0x0 // OK607 };608}609 610 611// =============================================================================612// # Array of __counted_by pointers613// =============================================================================614 615struct IncompleteTy3;616 617struct CBBufFAMofCountedByPtrs {618 int size;619 // TODO: This is misleading. The attribute is written in the type position620 // but clang currently doesn't treat it like that and it gets treated as621 // an attribute on the array, rather than on the element type.622 struct IncompleteTy3* __counted_by(size) arr[];623};624 625void arr_of_counted_by_ptr(struct CBBufFAMofCountedByPtrs* ptr) {626 // TODO: Should be disallowed once parsing attributes in the type position627 // works.628 ptr->arr[0] = 0x0;629 void* addr = ((char*) ptr->arr[0]) + 1;630}631