https://gcc.gnu.org/g:54c640ba3971d00b65cc48fef91dac6edc11dd09
commit r16-2075-g54c640ba3971d00b65cc48fef91dac6edc11dd09 Author: Qing Zhao <qing.z...@oracle.com> Date: Mon Jul 7 20:36:12 2025 +0000 Revert "Extend "counted_by" attribute to pointer fields of structures. Convert a pointer reference with counted_by attribute to .ACCESS_WITH_SIZE." due to PR120929. This reverts commit 687727375769dd41971bad369f3553f1163b3e7a. Diff: --- gcc/c-family/c-attribs.cc | 44 ++-------- gcc/c/c-decl.cc | 91 ++++++++----------- gcc/c/c-typeck.cc | 60 ++++--------- gcc/doc/extend.texi | 41 ++------- gcc/testsuite/gcc.dg/flex-array-counted-by.c | 2 +- gcc/testsuite/gcc.dg/pointer-counted-by-1.c | 34 ------- gcc/testsuite/gcc.dg/pointer-counted-by-2.c | 10 --- gcc/testsuite/gcc.dg/pointer-counted-by-3.c | 127 --------------------------- gcc/testsuite/gcc.dg/pointer-counted-by.c | 111 ----------------------- 9 files changed, 70 insertions(+), 450 deletions(-) diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index ea04ed7f0d45..5d7a31fd99b6 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -2906,53 +2906,22 @@ handle_counted_by_attribute (tree *node, tree name, " declaration %q+D", name, decl); *no_add_attrs = true; } - /* This attribute only applies to a field with array type or pointer type. */ - else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE - && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE) + /* This attribute only applies to field with array type. */ + else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE) { error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute is not allowed for a non-array" - " or non-pointer field", name); + "%qE attribute is not allowed for a non-array field", + name); *no_add_attrs = true; } /* This attribute only applies to a C99 flexible array member type. */ - else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && !c_flexible_array_member_type_p (TREE_TYPE (decl))) + else if (! c_flexible_array_member_type_p (TREE_TYPE (decl))) { error_at (DECL_SOURCE_LOCATION (decl), "%qE attribute is not allowed for a non-flexible" " array member field", name); *no_add_attrs = true; } - /* This attribute cannot be applied to a pointer to void type. */ - else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE) - { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute is not allowed for a pointer to void", - name); - *no_add_attrs = true; - } - /* This attribute cannot be applied to a pointer to function type. */ - else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE) - { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute is not allowed for a pointer to" - " function", name); - *no_add_attrs = true; - } - /* This attribute cannot be applied to a pointer to structure or union - with flexible array member. */ - else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE - && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (decl))) - && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (TREE_TYPE (decl)))) - { - error_at (DECL_SOURCE_LOCATION (decl), - "%qE attribute is not allowed for a pointer to" - " structure or union with flexible array member", name); - *no_add_attrs = true; - } /* The argument should be an identifier. */ else if (TREE_CODE (argval) != IDENTIFIER_NODE) { @@ -2961,8 +2930,7 @@ handle_counted_by_attribute (tree *node, tree name, *no_add_attrs = true; } /* Issue error when there is a counted_by attribute with a different - field as the argument for the same flexible array member or - pointer field. */ + field as the argument for the same flexible array member field. */ else if (old_counted_by != NULL_TREE) { tree old_fieldname = TREE_VALUE (TREE_VALUE (old_counted_by)); diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 7e1c197a7ed6..8bbd6ebc66ad 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9432,62 +9432,56 @@ c_update_type_canonical (tree t) } } -/* Verify the argument of the counted_by attribute of each of the - FIELDS_WITH_COUNTED_BY is a valid field of the containing structure, - STRUCT_TYPE, Report error and remove the corresponding attribute - when it's not. */ +/* Verify the argument of the counted_by attribute of the flexible array + member FIELD_DECL is a valid field of the containing structure, + STRUCT_TYPE, Report error and remove this attribute when it's not. */ static void -verify_counted_by_attribute (tree struct_type, - auto_vec<tree> *fields_with_counted_by) +verify_counted_by_attribute (tree struct_type, tree field_decl) { - for (tree field_decl : *fields_with_counted_by) - { - tree attr_counted_by = lookup_attribute ("counted_by", - DECL_ATTRIBUTES (field_decl)); + tree attr_counted_by = lookup_attribute ("counted_by", + DECL_ATTRIBUTES (field_decl)); - if (!attr_counted_by) - continue; + if (!attr_counted_by) + return; + + /* If there is an counted_by attribute attached to the field, + verify it. */ - /* If there is an counted_by attribute attached to the field, - verify it. */ + tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by)); - tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by)); + /* Verify the argument of the attrbute is a valid field of the + containing structure. */ - /* Verify the argument of the attrbute is a valid field of the - containing structure. */ + tree counted_by_field = lookup_field (struct_type, fieldname); - tree counted_by_field = lookup_field (struct_type, fieldname); + /* Error when the field is not found in the containing structure and + remove the corresponding counted_by attribute from the field_decl. */ + if (!counted_by_field) + { + error_at (DECL_SOURCE_LOCATION (field_decl), + "argument %qE to the %<counted_by%> attribute" + " is not a field declaration in the same structure" + " as %qD", fieldname, field_decl); + DECL_ATTRIBUTES (field_decl) + = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl)); + } + else + /* Error when the field is not with an integer type. */ + { + while (TREE_CHAIN (counted_by_field)) + counted_by_field = TREE_CHAIN (counted_by_field); + tree real_field = TREE_VALUE (counted_by_field); - /* Error when the field is not found in the containing structure and - remove the corresponding counted_by attribute from the field_decl. */ - if (!counted_by_field) + if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field))) { error_at (DECL_SOURCE_LOCATION (field_decl), "argument %qE to the %<counted_by%> attribute" - " is not a field declaration in the same structure" - " as %qD", fieldname, field_decl); + " is not a field declaration with an integer type", + fieldname); DECL_ATTRIBUTES (field_decl) = remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl)); } - else - /* Error when the field is not with an integer type. */ - { - while (TREE_CHAIN (counted_by_field)) - counted_by_field = TREE_CHAIN (counted_by_field); - tree real_field = TREE_VALUE (counted_by_field); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field))) - { - error_at (DECL_SOURCE_LOCATION (field_decl), - "argument %qE to the %<counted_by%> attribute" - " is not a field declaration with an integer type", - fieldname); - DECL_ATTRIBUTES (field_decl) - = remove_attribute ("counted_by", - DECL_ATTRIBUTES (field_decl)); - } - } } } @@ -9562,7 +9556,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, until now.) */ bool saw_named_field = false; - auto_vec<tree> fields_with_counted_by; + tree counted_by_fam_field = NULL_TREE; for (x = fieldlist; x; x = DECL_CHAIN (x)) { /* Whether this field is the last field of the structure or union. @@ -9643,16 +9637,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, record it here and do more verification later after the whole structure is complete. */ if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x))) - fields_with_counted_by.safe_push (x); + counted_by_fam_field = x; } - if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE) - /* If there is a counted_by attribute attached to this field, - record it here and do more verification later after the - whole structure is complete. */ - if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x))) - fields_with_counted_by.safe_push (x); - if (pedantic && TREE_CODE (t) == RECORD_TYPE && flexible_array_type_p (TREE_TYPE (x))) pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic, @@ -9951,8 +9938,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, struct_parse_info->struct_types.safe_push (t); } - if (fields_with_counted_by.length () > 0) - verify_counted_by_attribute (t, &fields_with_counted_by); + if (counted_by_fam_field) + verify_counted_by_attribute (t, counted_by_fam_field); return t; } diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 794810640e82..e24629be918b 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -2922,8 +2922,8 @@ should_suggest_deref_p (tree datum_type) /* For a SUBDATUM field of a structure or union DATUM, generate a REF to the object that represents its counted_by per the attribute counted_by - attached to this field if it's a flexible array member or a pointer - field, otherwise return NULL_TREE. + attached to this field if it's a flexible array member field, otherwise + return NULL_TREE. Set COUNTED_BY_TYPE to the TYPE of the counted_by field. For example, if: @@ -2941,34 +2941,18 @@ should_suggest_deref_p (tree datum_type) */ static tree -build_counted_by_ref (location_t loc, tree datum, tree subdatum, - tree *counted_by_type) +build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type) { tree type = TREE_TYPE (datum); - tree sub_type = TREE_TYPE (subdatum); - if (!c_flexible_array_member_type_p (sub_type) - && TREE_CODE (sub_type) != POINTER_TYPE) + if (!c_flexible_array_member_type_p (TREE_TYPE (subdatum))) return NULL_TREE; - tree element_type = TREE_TYPE (sub_type); - tree attr_counted_by = lookup_attribute ("counted_by", DECL_ATTRIBUTES (subdatum)); tree counted_by_ref = NULL_TREE; *counted_by_type = NULL_TREE; if (attr_counted_by) { - /* Issue error when the element_type is a structure or - union including a flexible array member. */ - if (RECORD_OR_UNION_TYPE_P (element_type) - && TYPE_INCLUDES_FLEXARRAY (element_type)) - { - error_at (loc, - "%<counted_by%> attribute is not allowed for a pointer to" - " structure or union with flexible array member"); - return error_mark_node; - } - tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by)); counted_by_ref = build_component_ref (UNKNOWN_LOCATION, @@ -2991,11 +2975,8 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum, } /* Given a COMPONENT_REF REF with the location LOC, the corresponding - COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate the corresponding - call to the internal function .ACCESS_WITH_SIZE. - - Generate an INDIRECT_REF to a call to the internal function - .ACCESS_WITH_SIZE. + COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate an INDIRECT_REF + to a call to the internal function .ACCESS_WITH_SIZE. REF @@ -3005,15 +2986,17 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum, (TYPE_OF_ARRAY *)0)) NOTE: The return type of this function is the POINTER type pointing - to the original flexible array type or the original pointer type. - Then the type of the INDIRECT_REF is the original flexible array type - or the original pointer type. + to the original flexible array type. + Then the type of the INDIRECT_REF is the original flexible array type. + + The type of the first argument of this function is a POINTER type + to the original flexible array type. The 4th argument of the call is a constant 0 with the TYPE of the object pointed by COUNTED_BY_REF. - The 6th argument of the call is a constant 0 of the same TYPE as - the return type of the call. + The 6th argument of the call is a constant 0 with the pointer TYPE + to the original flexible array type. */ static tree @@ -3021,16 +3004,11 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, tree counted_by_ref, tree counted_by_type) { - gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)) - || TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE); - bool is_fam = c_flexible_array_member_type_p (TREE_TYPE (ref)); - tree first_param = is_fam ? array_to_pointer_conversion (loc, ref) - : build_unary_op (loc, ADDR_EXPR, ref, false); - - /* The result type of the call is a pointer to the original type - of the ref. */ + gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))); + /* The result type of the call is a pointer to the flexible array type. */ tree result_type = c_build_pointer_type (TREE_TYPE (ref)); - first_param = c_fully_fold (first_param, false, NULL); + tree first_param + = c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL); tree second_param = c_fully_fold (counted_by_ref, false, NULL); @@ -3043,7 +3021,7 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, build_int_cst (counted_by_type, 0), build_int_cst (integer_type_node, -1), build_int_cst (result_type, 0)); - /* Wrap the call with an INDIRECT_REF with the original type of the ref. */ + /* Wrap the call with an INDIRECT_REF with the flexible array type. */ call = build1 (INDIRECT_REF, TREE_TYPE (ref), call); SET_EXPR_LOCATION (call, loc); return call; @@ -3061,7 +3039,7 @@ handle_counted_by_for_component_ref (location_t loc, tree ref) tree datum = TREE_OPERAND (ref, 0); tree subdatum = TREE_OPERAND (ref, 1); tree counted_by_type = NULL_TREE; - tree counted_by_ref = build_counted_by_ref (loc, datum, subdatum, + tree counted_by_ref = build_counted_by_ref (datum, subdatum, &counted_by_type); if (counted_by_ref) ref = build_access_with_size_for_counted_by (loc, ref, diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a119ad31ea2e..8c29e24c2670 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7138,11 +7138,9 @@ The @code{aligned} attribute can also be used for functions @cindex @code{counted_by} variable attribute @item counted_by (@var{count}) The @code{counted_by} attribute may be attached to the C99 flexible array -member, or a pointer field of a structure. It indicates that the number -of the elements of the array that is held by the flexible array member -field, or is pointed to by the pointer field, is given by the field -"@var{count}" in the same structure as the flexible array member or the -pointer field. +member of a structure. It indicates that the number of the elements of the +array is given by the field "@var{count}" in the same structure as the +flexible array member. This attribute is available only in C for now. In C++ this attribute is ignored. @@ -7163,22 +7161,8 @@ struct P @{ @end smallexample @noindent -specifies that the @code{array} is a flexible array member whose number -of elements is given by the field @code{count} in the same structure. - -@smallexample -struct PP @{ - size_t count2; - char other1; - char *array2 __attribute__ ((counted_by (count2))); - int other2; -@} *pp; -@end smallexample - -@noindent -specifies that the @code{array2} is an array that is pointed by the -pointer field, and its number of elements is given by the field -@code{count2} in the same structure. +specifies that the @code{array} is a flexible array member whose number of +elements is given by the field @code{count} in the same structure. The field that represents the number of the elements should have an integer type. Otherwise, the compiler reports an error and ignores @@ -7187,12 +7171,6 @@ the attribute. When the field that represents the number of the elements is assigned a negative integer value, the compiler treats the value as zero. -The @code{counted_by} attribute is not allowed for a pointer to @code{void}, -a pointer to function, or a pointer to a structure or union that includes -a flexible array member. However, it is allowed for a pointer to -non-void incomplete structure or union types, as long as the type could -be completed before the first reference to the pointer. - An explicit @code{counted_by} annotation defines a relationship between two objects, @code{p->array} and @code{p->count}, and there are the following requirements on the relationship between this pair: @@ -7208,13 +7186,6 @@ available all the time. This relationship must hold even after any of these related objects are updated during the program. @end itemize -In addition to the above requirements, there is one more requirement -between this pair if and only if @code{p->array} is an array that is -pointed by the pointer field: - -@code{p->array} and @code{p->count} can only be changed by changing the -whole structure at the same time. - It's the programmer's responsibility to make sure the above requirements to be kept all the time. Otherwise the compiler reports warnings and the results of the array bound sanitizer and the @@ -7236,8 +7207,6 @@ In the above, @code{ref1} uses @code{val1} as the number of the elements in @code{p->array}, and @code{ref2} uses @code{val2} as the number of elements in @code{p->array}. -Note, however, the above feature is not valid for the pointer field. - @cindex @code{alloc_size} variable attribute @item alloc_size (@var{position}) @itemx alloc_size (@var{position-1}, @var{position-2}) diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by.c b/gcc/testsuite/gcc.dg/flex-array-counted-by.c index 4fa91ff0bdb3..16eb2c630101 100644 --- a/gcc/testsuite/gcc.dg/flex-array-counted-by.c +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by.c @@ -10,7 +10,7 @@ int x __attribute ((counted_by (size))); /* { dg-error "attribute is not allowed struct trailing { int count; - int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */ + int field __attribute ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array field" } */ }; struct trailing_1 { diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-1.c b/gcc/testsuite/gcc.dg/pointer-counted-by-1.c deleted file mode 100644 index 395af3481b2f..000000000000 --- a/gcc/testsuite/gcc.dg/pointer-counted-by-1.c +++ /dev/null @@ -1,34 +0,0 @@ -/* More testing the correct usage of attribute counted_by for pointer field. */ -/* { dg-do compile } */ -/* { dg-options "-O0" } */ - -typedef struct item1 Item1; -typedef union item2 Item2; - -struct pointer_array { - int count1; - Item1 *array_1 __attribute__ ((counted_by (count1))); - Item2 *array_2 __attribute__ ((counted_by (count2))); - int count2; -} *pointer_data; - -struct item1 { - int a; - float b[]; -}; - -union item2 { - int c; - float d[]; -}; - -void foo () -{ - pointer_data - = (struct pointer_array *) __builtin_malloc (sizeof (struct pointer_array)); - pointer_data->array_1 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */ - = (Item1 *) __builtin_malloc (sizeof (Item1) + 3 * sizeof (float)); - pointer_data->array_2 /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */ - = (Item2 *) __builtin_malloc (sizeof (Item2) + 3 * sizeof (float)); - return; -} diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-2.c b/gcc/testsuite/gcc.dg/pointer-counted-by-2.c deleted file mode 100644 index 1f4a278052c5..000000000000 --- a/gcc/testsuite/gcc.dg/pointer-counted-by-2.c +++ /dev/null @@ -1,10 +0,0 @@ -/* Testing the correct usage of attribute counted_by for pointer: _BitInt */ -/* { dg-do compile { target bitint } } */ -/* { dg-options "-O2 -std=c23" } */ - -struct pointer_array { - _BitInt(24) count; - int *array __attribute__ ((counted_by (count))); - int *array1 __attribute__ ((counted_by (count1))); - _BitInt(24) count1; -}; diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-3.c b/gcc/testsuite/gcc.dg/pointer-counted-by-3.c deleted file mode 100644 index 700560983649..000000000000 --- a/gcc/testsuite/gcc.dg/pointer-counted-by-3.c +++ /dev/null @@ -1,127 +0,0 @@ - /* Testing the correct usage of attribute counted_by for pointer in c23, - multiple definitions of the same tag in same or different scopes. - { dg-do compile } - { dg-options "-std=c23" } - */ - -/* Allowed redefinitions of the same struct in the same scope, with the - same counted_by attribute. */ -struct f { - int b; - int c; - int *a __attribute__ ((counted_by (b))); }; -struct f { - int b; - int c; - int *a __attribute__ ((counted_by (b))); }; -struct f { - int b; - int c; - int *a; }; /* { dg-error "redefinition of struct or union" } */ - -/* Error when the counted_by attribute is defined differently. */ -struct f { - int b; - int c; - int *a __attribute__ ((counted_by (c))); }; /* { dg-error "redefinition of struct or union" } */ - -struct h { - int b; - int c; - int *a __attribute__ ((counted_by (b))); } p; - -void test (void) -{ - struct h { - int b; - int c; - int *a __attribute__ ((counted_by (b))); } x; - - p = x; -} - -void test1 (void) -{ - struct h { - int b; - int c; - int *a __attribute__ ((counted_by (c))); } y; - - p = y; /* { dg-error "incompatible types when assigning to type" } */ -} - -struct nested_f { - struct { - union { - int b; - float f; - }; - int n; - }; - char *c __attribute__ ((counted_by (b))); -}; - -struct nested_f { - struct { - union { - int b; - float f; - }; - int n; - }; - char *c __attribute__ ((counted_by (b))); -}; - -struct nested_f { - struct { - union { - int b; - float f; - }; - int n; - }; - char *c __attribute__ ((counted_by (n))); -}; /* { dg-error "redefinition of struct or union" } */ - -struct nested_h { - struct { - union { - int b; - float f; - }; - int n; - }; - char *c __attribute__ ((counted_by (b))); -} nested_p; - -void test_2 (void) -{ -struct nested_h { - struct { - union { - int b; - float f; - }; - int n; - }; - char *c __attribute__ ((counted_by (b))); -} nested_x; - - nested_p = nested_x; -} - -void test_3 (void) -{ -struct nested_h { - struct { - union { - int b; - float f; - }; - int n; - }; - char *c __attribute__ ((counted_by (n))); -} nested_y; - - nested_p = nested_y; /* { dg-error "incompatible types when assigning to type" } */ -} diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by.c b/gcc/testsuite/gcc.dg/pointer-counted-by.c deleted file mode 100644 index 0f18828ac113..000000000000 --- a/gcc/testsuite/gcc.dg/pointer-counted-by.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Testing the correct usage of attribute counted_by for pointer field. - and also mixed pointer field and FMA field in the same structure. */ -/* { dg-do compile } */ -/* { dg-options "-O0" } */ - -int size; -int *x __attribute__ ((counted_by (size))); /* { dg-error "attribute is not allowed for a non-field declaration" } */ - -struct pointer_array_0 { - int count; - int array __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a non-array or non-pointer field" } */ - int other; -}; - -int count; -struct pointer_array_1 { - int other; - int *array_1 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */ - int array_fam[] __attribute__ ((counted_by (count))); /* { dg-error "attribute is not a field declaration in the same structure as" } */ -}; - -struct pointer_array_2 { - float count1; - float count2; - int *array_2 __attribute__ ((counted_by (count1))); /* { dg-error "attribute is not a field declaration with an integer type" } */ - int array_fam[] __attribute__ ((counted_by (count2))); /* { dg-error "attribute is not a field declaration with an integer type" } */ -}; - -struct pointer_array_3 { - int count; - int *array_3 __attribute__ ((counted_by (count))) __attribute__ ((counted_by (count))); -}; - -struct pointer_array_4 { - int count1; - int count2; - int *array_4 __attribute__ ((counted_by (count1))) __attribute__ ((counted_by (count2))); /* { dg-error "conflicts with previous declaration" } */ - float array_fam[] __attribute__ ((counted_by (count2))) __attribute__ ((counted_by (count1))); /* { dg-error "conflicts with previous declaration" } */ -}; - -struct pointer_array_5 { - _Bool count; - int *array_5 __attribute__ ((counted_by (count))); -}; - -enum week {Mon, Tue, Wed}; -struct pointer_array_6 { - enum week days; - int *array_6 __attribute__ ((counted_by (days))); -}; - -struct pointer_array_7 { - int count; - void *array_7 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to void" } */ -}; - -struct pointer_array_8 { - int count; - int (*fpr)(int,int) __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to function" } */ -}; - -struct item1 { - int a; - float b; -}; - -union item2 { - char *a; - int *b; -}; - -typedef struct item3 Item3; -typedef union item4 Item4; - -struct item5 { - int a; - float b[]; -}; - -/* Incomplete structure and union are allowed. */ -struct pointer_array_9 { - int count1; - int count2; - int count3; - struct item1 *array_1 __attribute__ ((counted_by (count1))); - union item2 *array_2 __attribute__ ((counted_by (count2))); - Item3 *array_3 __attribute__ ((counted_by (count3))); - Item4 *array_4 __attribute__ ((counted_by (count4))); - int count4; - int count5; - /* structure with flexible array member is not allowed. */ - struct item5 *array_5 __attribute__ ((counted_by (count5))); /* { dg-error "attribute is not allowed for a pointer to structure or union with flexible array member" } */ -}; - -struct mixed_array { - int count1; - float *array_1 __attribute__ ((counted_by (count1))); - float *array_2 __attribute__ ((counted_by (count1))); - int count2; - long *array_3 __attribute__ ((counted_by (count2))); - long array_4[] __attribute__ ((counted_by (count2))); -}; - -struct mixed_array_2 { - float *array_1 __attribute__ ((counted_by (count1))); - int count1; - float *array_2 __attribute__ ((counted_by (count1))); - long *array_3 __attribute__ ((counted_by (count2))); - int count2; - long array_4[] __attribute__ ((counted_by (count2))); -};