199 lines · c
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,immediate %s2// RUN: %clang_cc1 -fsyntax-only -fexperimental-late-parse-attributes %s -verify=expected,late3 4#define __counted_by(f) __attribute__((counted_by(f)))5 6struct bar;7 8struct not_found {9 int count;10 struct bar *fam[] __counted_by(bork); // expected-error {{use of undeclared identifier 'bork'}}11};12 13struct no_found_count_not_in_substruct {14 unsigned long flags;15 unsigned char count; // expected-note {{'count' declared here}}16 struct A {17 int dummy;18 int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the annotated flexible array}}19 } a;20};21 22struct not_found_count_not_in_unnamed_substruct {23 unsigned char count; // expected-note {{'count' declared here}}24 struct {25 int dummy;26 int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the annotated flexible array}}27 } a;28};29 30struct not_found_count_not_in_unnamed_substruct_2 {31 struct {32 unsigned char count; // expected-note {{'count' declared here}}33 };34 struct {35 int dummy;36 int array[] __counted_by(count); // expected-error {{'counted_by' field 'count' isn't within the same struct as the annotated flexible array}}37 } a;38};39 40struct not_found_count_in_other_unnamed_substruct {41 struct {42 unsigned char count;43 } a1;44 45 struct {46 int dummy;47 int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}}48 };49};50 51struct not_found_count_in_other_substruct {52 struct _a1 {53 unsigned char count;54 } a1;55 56 struct {57 int dummy;58 int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}}59 };60};61 62struct not_found_count_in_other_substruct_2 {63 struct _a2 {64 unsigned char count;65 } a2;66 67 int array[] __counted_by(count); // expected-error {{use of undeclared identifier 'count'}}68};69 70struct not_found_suggest {71 int bork;72 struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'}}73};74 75int global; // expected-note {{'global' declared here}}76 77struct found_outside_of_struct {78 int bork;79 struct bar *fam[] __counted_by(global); // expected-error {{field 'global' in 'counted_by' not inside structure}}80};81 82struct self_referrential {83 int bork;84 // immediate-error@+2{{use of undeclared identifier 'self'}}85 // late-error@+1{{'counted_by' requires a non-boolean integer type argument}}86 struct bar *self[] __counted_by(self);87};88 89struct non_int_count {90 double dbl_count;91 struct bar *fam[] __counted_by(dbl_count); // expected-error {{'counted_by' requires a non-boolean integer type argument}}92};93 94struct array_of_ints_count {95 int integers[2];96 struct bar *fam[] __counted_by(integers); // expected-error {{'counted_by' requires a non-boolean integer type argument}}97};98 99struct not_a_fam {100 int count;101 struct bar *non_fam __counted_by(count); // ok102};103 104struct not_a_c99_fam {105 int count;106 struct bar *non_c99_fam[0] __counted_by(count); // expected-error {{'counted_by' on arrays only applies to C99 flexible array members}}107};108 109struct annotated_with_anon_struct {110 unsigned long flags;111 struct {112 unsigned char count;113 int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'}}114 };115};116 117//==============================================================================118// __counted_by on a struct VLA with element type that has unknown size119//==============================================================================120 121struct size_unknown; // expected-note 2{{forward declaration of 'struct size_unknown'}}122struct on_member_arr_incomplete_ty_ty_pos {123 int count;124 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}}125 // expected-error@+1{{array has incomplete element type 'struct size_unknown'}}126 struct size_unknown buf[] __counted_by(count);127};128 129struct on_member_arr_incomplete_const_ty_ty_pos {130 int count;131 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}}132 // expected-error@+1{{array has incomplete element type 'const struct size_unknown'}}133 const struct size_unknown buf[] __counted_by(count);134};135 136struct on_member_arr_void_ty_ty_pos {137 int count;138 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}}139 // expected-error@+1{{array has incomplete element type 'void'}}140 void buf[] __counted_by(count);141};142 143typedef void(fn_ty)(int);144 145struct on_member_arr_fn_ptr_ty {146 int count;147 // An Array of function pointers is allowed148 fn_ty* buf[] __counted_by(count);149};150 151struct on_member_arr_fn_ty {152 int count;153 // An array of functions is not allowed.154 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}}155 // expected-error@+1{{'buf' declared as array of functions of type 'fn_ty' (aka 'void (int)')}}156 fn_ty buf[] __counted_by(count);157};158 159 160// `buffer_of_structs_with_unnannotated_vla`,161// `buffer_of_structs_with_annotated_vla`, and162// `buffer_of_const_structs_with_annotated_vla` are currently prevented because163// computing the size of `Arr` at runtime would require an O(N) walk of `Arr`164// elements to take into account the length of the VLA in each struct instance.165 166struct has_unannotated_VLA {167 int count;168 char buffer[];169};170 171struct has_annotated_VLA {172 int count;173 char buffer[] __counted_by(count);174};175 176struct buffer_of_structs_with_unnannotated_vla {177 int count;178 // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**.179 // expected-warning@+1{{'counted_by' should not be applied to an array with element of unknown size because 'struct has_unannotated_VLA' is a struct type with a flexible array member. This will be an error in a future compiler version}}180 struct has_unannotated_VLA Arr[] __counted_by(count);181};182 183 184struct buffer_of_structs_with_annotated_vla {185 int count;186 // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**.187 // expected-warning@+1{{'counted_by' should not be applied to an array with element of unknown size because 'struct has_annotated_VLA' is a struct type with a flexible array member. This will be an error in a future compiler version}}188 struct has_annotated_VLA Arr[] __counted_by(count);189};190 191struct buffer_of_const_structs_with_annotated_vla {192 int count;193 // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**.194 // Make sure the `const` qualifier is printed when printing the element type.195 // expected-warning@+1{{'counted_by' should not be applied to an array with element of unknown size because 'const struct has_annotated_VLA' is a struct type with a flexible array member. This will be an error in a future compiler version}}196 const struct has_annotated_VLA Arr[] __counted_by(count);197};198 199