diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 91 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 60 |
3 files changed, 75 insertions, 93 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index cb69b8c..dcef284 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,20 @@ +2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + Revert: + 2025-07-07 Qing Zhao <qing.zhao@oracle.com> + + * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument + to a vector of fields with counted_by attribute. Verify all fields + in this vector. + (finish_struct): Collect all the fields with counted_by attribute + to a vector and pass this vector to verify_counted_by_attribute. + * c-typeck.cc (build_counted_by_ref): Handle pointers with counted_by. + Add one more argument, issue error when the pointee type is a structure + or union including a flexible array member. + (build_access_with_size_for_counted_by): Handle pointers with counted_by. + (handle_counted_by_for_component_ref): Call build_counted_by_ref + with the new prototype. + 2025-07-01 Qing Zhao <qing.zhao@oracle.com> * c-decl.cc (verify_counted_by_attribute): Change the 2nd argument diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 7e1c197..8bbd6eb 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 7948106..e24629b 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, |