146 lines · c
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,immediate %s2// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify=expected,late %s3 4#define __sized_by(f) __attribute__((sized_by(f)))5 6// This has been adapted from clang/test/Sema/attr-counted-by-vla.c, but with VLAs replaced with pointers7 8struct bar;9 10struct not_found {11 int size;12 struct bar *ptr __sized_by(bork); // expected-error {{use of undeclared identifier 'bork'}}13};14 15struct no_found_size_not_in_substruct {16 unsigned long flags;17 unsigned char size; // expected-note {{'size' declared here}}18 struct A {19 int dummy;20 int * ptr __sized_by(size); // expected-error {{'sized_by' field 'size' isn't within the same struct as the annotated pointer}}21 } a;22};23 24struct not_found_size_not_in_unnamed_substruct {25 unsigned char size; // expected-note {{'size' declared here}}26 struct {27 int dummy;28 int * ptr __sized_by(size); // expected-error {{'sized_by' field 'size' isn't within the same struct as the annotated pointer}}29 } a;30};31 32struct not_found_size_not_in_unnamed_substruct_2 {33 struct {34 unsigned char size; // expected-note {{'size' declared here}}35 };36 struct {37 int dummy;38 int * ptr __sized_by(size); // expected-error {{'sized_by' field 'size' isn't within the same struct as the annotated pointer}}39 } a;40};41 42struct not_found_size_in_other_unnamed_substruct {43 struct {44 unsigned char size;45 } a1;46 47 struct {48 int dummy;49 int * ptr __sized_by(size); // expected-error {{use of undeclared identifier 'size'}}50 };51};52 53struct not_found_size_in_other_substruct {54 struct _a1 {55 unsigned char size;56 } a1;57 58 struct {59 int dummy;60 int * ptr __sized_by(size); // expected-error {{use of undeclared identifier 'size'}}61 };62};63 64struct not_found_size_in_other_substruct_2 {65 struct _a2 {66 unsigned char size;67 } a2;68 69 int * ptr __sized_by(size); // expected-error {{use of undeclared identifier 'size'}}70};71 72struct not_found_suggest {73 int bork;74 struct bar **ptr __sized_by(blork); // expected-error {{use of undeclared identifier 'blork'}}75};76 77int global; // expected-note {{'global' declared here}}78 79struct found_outside_of_struct {80 int bork;81 struct bar ** ptr __sized_by(global); // expected-error {{field 'global' in 'sized_by' not inside structure}}82};83 84struct self_referrential {85 int bork;86 // immediate-error@+2{{use of undeclared identifier 'self'}}87 // late-error@+1{{'sized_by' only applies to pointers; did you mean to use 'counted_by'?}}88 struct bar *self[] __sized_by(self);89};90 91struct non_int_size {92 double dbl_size;93 struct bar ** ptr __sized_by(dbl_size); // expected-error {{'sized_by' requires a non-boolean integer type argument}}94};95 96struct array_of_ints_size {97 int integers[2];98 struct bar ** ptr __sized_by(integers); // expected-error {{'sized_by' requires a non-boolean integer type argument}}99};100 101struct not_a_c99_fam {102 int size;103 struct bar *non_c99_fam[0] __sized_by(size); // expected-error {{'sized_by' only applies to pointers; did you mean to use 'counted_by'?}}104};105 106struct annotated_with_anon_struct {107 unsigned long flags;108 struct {109 unsigned char size;110 int * ptr __sized_by(crount); // expected-error {{use of undeclared identifier 'crount'}}111 };112};113 114//==============================================================================115// __sized_by on a struct ptr with element type that has unknown size116//==============================================================================117 118struct size_unknown;119struct on_member_ptr_incomplete_ty_ty_pos {120 int size;121 struct size_unknown * ptr __sized_by(size);122};123 124struct on_member_ptr_incomplete_const_ty_ty_pos {125 int size;126 const struct size_unknown * ptr __sized_by(size);127};128 129struct on_member_ptr_void_ty_ty_pos {130 int size;131 void * ptr __sized_by(size);132};133 134typedef void(fn_ty)(int);135 136struct on_member_ptr_fn_ptr_ty {137 int size;138 fn_ty* * ptr __sized_by(size);139};140 141struct on_member_ptr_fn_ty {142 int size;143 // expected-error@+1{{'sized_by' cannot be applied to a pointer with pointee of unknown size because 'fn_ty' (aka 'void (int)') is a function type}}144 fn_ty * ptr __sized_by(size);145};146