1 // RUN: %clang_cc1 -fsyntax-only -verify=expected,immediate %s 2 // RUN: %clang_cc1 -fsyntax-only -fexperimental-late-parse-attributes %s -verify=expected,late 3 4 #define __counted_by(f) __attribute__((counted_by(f))) 5 6 struct bar; 7 8 struct not_found { 9 int count; 10 struct bar *fam[] __counted_by(bork); // expected-error {{use of undeclared identifier 'bork'}} 11 }; 12 13 struct 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 22 struct 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 30 struct 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 40 struct 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 51 struct 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 62 struct 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 70 struct not_found_suggest { 71 int bork; 72 struct bar *fam[] __counted_by(blork); // expected-error {{use of undeclared identifier 'blork'}} 73 }; 74 75 int global; // expected-note {{'global' declared here}} 76 77 struct 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 82 struct 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 89 struct 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 94 struct 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 99 struct not_a_fam { 100 int count; 101 // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct bar' is an incomplete type}} 102 struct bar *non_fam __counted_by(count); 103 }; 104 105 struct not_a_c99_fam { 106 int count; 107 struct bar *non_c99_fam[0] __counted_by(count); // expected-error {{'counted_by' on arrays only applies to C99 flexible array members}} 108 }; 109 110 struct annotated_with_anon_struct { 111 unsigned long flags; 112 struct { 113 unsigned char count; 114 int array[] __counted_by(crount); // expected-error {{use of undeclared identifier 'crount'}} 115 }; 116 }; 117 118 //============================================================================== 119 // __counted_by on a struct VLA with element type that has unknown size 120 //============================================================================== 121 122 struct size_unknown; // expected-note 2{{forward declaration of 'struct size_unknown'}} 123 struct on_member_arr_incomplete_ty_ty_pos { 124 int count; 125 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} 126 // expected-error@+1{{array has incomplete element type 'struct size_unknown'}} 127 struct size_unknown buf[] __counted_by(count); 128 }; 129 130 struct on_member_arr_incomplete_const_ty_ty_pos { 131 int count; 132 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} 133 // expected-error@+1{{array has incomplete element type 'const struct size_unknown'}} 134 const struct size_unknown buf[] __counted_by(count); 135 }; 136 137 struct on_member_arr_void_ty_ty_pos { 138 int count; 139 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} 140 // expected-error@+1{{array has incomplete element type 'void'}} 141 void buf[] __counted_by(count); 142 }; 143 144 typedef void(fn_ty)(int); 145 146 struct on_member_arr_fn_ptr_ty { 147 int count; 148 // An Array of function pointers is allowed 149 fn_ty* buf[] __counted_by(count); 150 }; 151 152 struct on_member_arr_fn_ty { 153 int count; 154 // An array of functions is not allowed. 155 // expected-error@+2{{'counted_by' only applies to pointers or C99 flexible array members}} 156 // expected-error@+1{{'buf' declared as array of functions of type 'fn_ty' (aka 'void (int)')}} 157 fn_ty buf[] __counted_by(count); 158 }; 159 160 161 // `buffer_of_structs_with_unnannotated_vla`, 162 // `buffer_of_structs_with_annotated_vla`, and 163 // `buffer_of_const_structs_with_annotated_vla` are currently prevented because 164 // computing the size of `Arr` at runtime would require an O(N) walk of `Arr` 165 // elements to take into account the length of the VLA in each struct instance. 166 167 struct has_unannotated_VLA { 168 int count; 169 char buffer[]; 170 }; 171 172 struct has_annotated_VLA { 173 int count; 174 char buffer[] __counted_by(count); 175 }; 176 177 struct buffer_of_structs_with_unnannotated_vla { 178 int count; 179 // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**. 180 // 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}} 181 struct has_unannotated_VLA Arr[] __counted_by(count); 182 }; 183 184 185 struct buffer_of_structs_with_annotated_vla { 186 int count; 187 // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**. 188 // 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}} 189 struct has_annotated_VLA Arr[] __counted_by(count); 190 }; 191 192 struct buffer_of_const_structs_with_annotated_vla { 193 int count; 194 // Treating this as a warning is a temporary fix for existing attribute adopters. It **SHOULD BE AN ERROR**. 195 // Make sure the `const` qualifier is printed when printing the element type. 196 // 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}} 197 const struct has_annotated_VLA Arr[] __counted_by(count); 198 }; 199 200