brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.1 KiB · cff5a14 Raw
632 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_or_null(f)  __attribute__((counted_by_or_null(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_or_null(count); // OK expected-note 27{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}25  Incomplete_t* buf_typedef __counted_by_or_null(count); // OK expected-note 27{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(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_or_null' attributed type 'Incomplete_t * __counted_by_or_null(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_or_null(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_or_null(count) buf ; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}363  Incomplete_ty2 *__counted_by_or_null(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(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_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(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_or_null(count) buf ; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}437  IncompleteUnion_ty *__counted_by_or_null(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(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_or_null(count) buf ; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}511  IncompleteEnum_ty *__counted_by_or_null(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}}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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(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_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(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_or_null(count) buf;579  CompleteEnum_ty *__counted_by_or_null(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_or_null(count) buf;599  CompleteEnum_ty2 *__counted_by_or_null(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_or_null 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  // expected-error@+1{{'counted_by_or_null' only applies to pointers; did you mean to use 'counted_by'?}}623  struct IncompleteTy3* __counted_by_or_null(size) arr[];624};625 626void arr_of_counted_by_ptr(struct CBBufFAMofCountedByPtrs* ptr) {627  // TODO: Should be disallowed once parsing attributes in the type position628  // works.629  ptr->arr[0] = 0x0;630  void* addr = ((char*) ptr->arr[0]) + 1;631}632