Skip to content

Commit 54c640b

Browse files
committed
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 6877273.
1 parent bed3415 commit 54c640b

File tree

9 files changed

+70
-450
lines changed

9 files changed

+70
-450
lines changed

gcc/c-family/c-attribs.cc

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,53 +2906,22 @@ handle_counted_by_attribute (tree *node, tree name,
29062906
" declaration %q+D", name, decl);
29072907
*no_add_attrs = true;
29082908
}
2909-
/* This attribute only applies to a field with array type or pointer type. */
2910-
else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
2911-
&& TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
2909+
/* This attribute only applies to field with array type. */
2910+
else if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
29122911
{
29132912
error_at (DECL_SOURCE_LOCATION (decl),
2914-
"%qE attribute is not allowed for a non-array"
2915-
" or non-pointer field", name);
2913+
"%qE attribute is not allowed for a non-array field",
2914+
name);
29162915
*no_add_attrs = true;
29172916
}
29182917
/* This attribute only applies to a C99 flexible array member type. */
2919-
else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2920-
&& !c_flexible_array_member_type_p (TREE_TYPE (decl)))
2918+
else if (! c_flexible_array_member_type_p (TREE_TYPE (decl)))
29212919
{
29222920
error_at (DECL_SOURCE_LOCATION (decl),
29232921
"%qE attribute is not allowed for a non-flexible"
29242922
" array member field", name);
29252923
*no_add_attrs = true;
29262924
}
2927-
/* This attribute cannot be applied to a pointer to void type. */
2928-
else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
2929-
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
2930-
{
2931-
error_at (DECL_SOURCE_LOCATION (decl),
2932-
"%qE attribute is not allowed for a pointer to void",
2933-
name);
2934-
*no_add_attrs = true;
2935-
}
2936-
/* This attribute cannot be applied to a pointer to function type. */
2937-
else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
2938-
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
2939-
{
2940-
error_at (DECL_SOURCE_LOCATION (decl),
2941-
"%qE attribute is not allowed for a pointer to"
2942-
" function", name);
2943-
*no_add_attrs = true;
2944-
}
2945-
/* This attribute cannot be applied to a pointer to structure or union
2946-
with flexible array member. */
2947-
else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
2948-
&& RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
2949-
&& TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (TREE_TYPE (decl))))
2950-
{
2951-
error_at (DECL_SOURCE_LOCATION (decl),
2952-
"%qE attribute is not allowed for a pointer to"
2953-
" structure or union with flexible array member", name);
2954-
*no_add_attrs = true;
2955-
}
29562925
/* The argument should be an identifier. */
29572926
else if (TREE_CODE (argval) != IDENTIFIER_NODE)
29582927
{
@@ -2961,8 +2930,7 @@ handle_counted_by_attribute (tree *node, tree name,
29612930
*no_add_attrs = true;
29622931
}
29632932
/* Issue error when there is a counted_by attribute with a different
2964-
field as the argument for the same flexible array member or
2965-
pointer field. */
2933+
field as the argument for the same flexible array member field. */
29662934
else if (old_counted_by != NULL_TREE)
29672935
{
29682936
tree old_fieldname = TREE_VALUE (TREE_VALUE (old_counted_by));

gcc/c/c-decl.cc

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9432,62 +9432,56 @@ c_update_type_canonical (tree t)
94329432
}
94339433
}
94349434

9435-
/* Verify the argument of the counted_by attribute of each of the
9436-
FIELDS_WITH_COUNTED_BY is a valid field of the containing structure,
9437-
STRUCT_TYPE, Report error and remove the corresponding attribute
9438-
when it's not. */
9435+
/* Verify the argument of the counted_by attribute of the flexible array
9436+
member FIELD_DECL is a valid field of the containing structure,
9437+
STRUCT_TYPE, Report error and remove this attribute when it's not. */
94399438

94409439
static void
9441-
verify_counted_by_attribute (tree struct_type,
9442-
auto_vec<tree> *fields_with_counted_by)
9440+
verify_counted_by_attribute (tree struct_type, tree field_decl)
94439441
{
9444-
for (tree field_decl : *fields_with_counted_by)
9445-
{
9446-
tree attr_counted_by = lookup_attribute ("counted_by",
9447-
DECL_ATTRIBUTES (field_decl));
9442+
tree attr_counted_by = lookup_attribute ("counted_by",
9443+
DECL_ATTRIBUTES (field_decl));
94489444

9449-
if (!attr_counted_by)
9450-
continue;
9445+
if (!attr_counted_by)
9446+
return;
9447+
9448+
/* If there is an counted_by attribute attached to the field,
9449+
verify it. */
94519450

9452-
/* If there is an counted_by attribute attached to the field,
9453-
verify it. */
9451+
tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by));
94549452

9455-
tree fieldname = TREE_VALUE (TREE_VALUE (attr_counted_by));
9453+
/* Verify the argument of the attrbute is a valid field of the
9454+
containing structure. */
94569455

9457-
/* Verify the argument of the attrbute is a valid field of the
9458-
containing structure. */
9456+
tree counted_by_field = lookup_field (struct_type, fieldname);
94599457

9460-
tree counted_by_field = lookup_field (struct_type, fieldname);
9458+
/* Error when the field is not found in the containing structure and
9459+
remove the corresponding counted_by attribute from the field_decl. */
9460+
if (!counted_by_field)
9461+
{
9462+
error_at (DECL_SOURCE_LOCATION (field_decl),
9463+
"argument %qE to the %<counted_by%> attribute"
9464+
" is not a field declaration in the same structure"
9465+
" as %qD", fieldname, field_decl);
9466+
DECL_ATTRIBUTES (field_decl)
9467+
= remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl));
9468+
}
9469+
else
9470+
/* Error when the field is not with an integer type. */
9471+
{
9472+
while (TREE_CHAIN (counted_by_field))
9473+
counted_by_field = TREE_CHAIN (counted_by_field);
9474+
tree real_field = TREE_VALUE (counted_by_field);
94619475

9462-
/* Error when the field is not found in the containing structure and
9463-
remove the corresponding counted_by attribute from the field_decl. */
9464-
if (!counted_by_field)
9476+
if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field)))
94659477
{
94669478
error_at (DECL_SOURCE_LOCATION (field_decl),
94679479
"argument %qE to the %<counted_by%> attribute"
9468-
" is not a field declaration in the same structure"
9469-
" as %qD", fieldname, field_decl);
9480+
" is not a field declaration with an integer type",
9481+
fieldname);
94709482
DECL_ATTRIBUTES (field_decl)
94719483
= remove_attribute ("counted_by", DECL_ATTRIBUTES (field_decl));
94729484
}
9473-
else
9474-
/* Error when the field is not with an integer type. */
9475-
{
9476-
while (TREE_CHAIN (counted_by_field))
9477-
counted_by_field = TREE_CHAIN (counted_by_field);
9478-
tree real_field = TREE_VALUE (counted_by_field);
9479-
9480-
if (!INTEGRAL_TYPE_P (TREE_TYPE (real_field)))
9481-
{
9482-
error_at (DECL_SOURCE_LOCATION (field_decl),
9483-
"argument %qE to the %<counted_by%> attribute"
9484-
" is not a field declaration with an integer type",
9485-
fieldname);
9486-
DECL_ATTRIBUTES (field_decl)
9487-
= remove_attribute ("counted_by",
9488-
DECL_ATTRIBUTES (field_decl));
9489-
}
9490-
}
94919485
}
94929486
}
94939487

@@ -9562,7 +9556,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
95629556
until now.) */
95639557

95649558
bool saw_named_field = false;
9565-
auto_vec<tree> fields_with_counted_by;
9559+
tree counted_by_fam_field = NULL_TREE;
95669560
for (x = fieldlist; x; x = DECL_CHAIN (x))
95679561
{
95689562
/* 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,
96439637
record it here and do more verification later after the
96449638
whole structure is complete. */
96459639
if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x)))
9646-
fields_with_counted_by.safe_push (x);
9640+
counted_by_fam_field = x;
96479641
}
96489642

9649-
if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
9650-
/* If there is a counted_by attribute attached to this field,
9651-
record it here and do more verification later after the
9652-
whole structure is complete. */
9653-
if (lookup_attribute ("counted_by", DECL_ATTRIBUTES (x)))
9654-
fields_with_counted_by.safe_push (x);
9655-
96569643
if (pedantic && TREE_CODE (t) == RECORD_TYPE
96579644
&& flexible_array_type_p (TREE_TYPE (x)))
96589645
pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
@@ -9951,8 +9938,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
99519938
struct_parse_info->struct_types.safe_push (t);
99529939
}
99539940

9954-
if (fields_with_counted_by.length () > 0)
9955-
verify_counted_by_attribute (t, &fields_with_counted_by);
9941+
if (counted_by_fam_field)
9942+
verify_counted_by_attribute (t, counted_by_fam_field);
99569943

99579944
return t;
99589945
}

gcc/c/c-typeck.cc

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,8 +2922,8 @@ should_suggest_deref_p (tree datum_type)
29222922

29232923
/* For a SUBDATUM field of a structure or union DATUM, generate a REF to
29242924
the object that represents its counted_by per the attribute counted_by
2925-
attached to this field if it's a flexible array member or a pointer
2926-
field, otherwise return NULL_TREE.
2925+
attached to this field if it's a flexible array member field, otherwise
2926+
return NULL_TREE.
29272927
Set COUNTED_BY_TYPE to the TYPE of the counted_by field.
29282928
For example, if:
29292929

@@ -2941,34 +2941,18 @@ should_suggest_deref_p (tree datum_type)
29412941

29422942
*/
29432943
static tree
2944-
build_counted_by_ref (location_t loc, tree datum, tree subdatum,
2945-
tree *counted_by_type)
2944+
build_counted_by_ref (tree datum, tree subdatum, tree *counted_by_type)
29462945
{
29472946
tree type = TREE_TYPE (datum);
2948-
tree sub_type = TREE_TYPE (subdatum);
2949-
if (!c_flexible_array_member_type_p (sub_type)
2950-
&& TREE_CODE (sub_type) != POINTER_TYPE)
2947+
if (!c_flexible_array_member_type_p (TREE_TYPE (subdatum)))
29512948
return NULL_TREE;
29522949

2953-
tree element_type = TREE_TYPE (sub_type);
2954-
29552950
tree attr_counted_by = lookup_attribute ("counted_by",
29562951
DECL_ATTRIBUTES (subdatum));
29572952
tree counted_by_ref = NULL_TREE;
29582953
*counted_by_type = NULL_TREE;
29592954
if (attr_counted_by)
29602955
{
2961-
/* Issue error when the element_type is a structure or
2962-
union including a flexible array member. */
2963-
if (RECORD_OR_UNION_TYPE_P (element_type)
2964-
&& TYPE_INCLUDES_FLEXARRAY (element_type))
2965-
{
2966-
error_at (loc,
2967-
"%<counted_by%> attribute is not allowed for a pointer to"
2968-
" structure or union with flexible array member");
2969-
return error_mark_node;
2970-
}
2971-
29722956
tree field_id = TREE_VALUE (TREE_VALUE (attr_counted_by));
29732957
counted_by_ref
29742958
= build_component_ref (UNKNOWN_LOCATION,
@@ -2991,11 +2975,8 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum,
29912975
}
29922976

29932977
/* Given a COMPONENT_REF REF with the location LOC, the corresponding
2994-
COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate the corresponding
2995-
call to the internal function .ACCESS_WITH_SIZE.
2996-
2997-
Generate an INDIRECT_REF to a call to the internal function
2998-
.ACCESS_WITH_SIZE.
2978+
COUNTED_BY_REF, and the COUNTED_BY_TYPE, generate an INDIRECT_REF
2979+
to a call to the internal function .ACCESS_WITH_SIZE.
29992980

30002981
REF
30012982

@@ -3005,32 +2986,29 @@ build_counted_by_ref (location_t loc, tree datum, tree subdatum,
30052986
(TYPE_OF_ARRAY *)0))
30062987

30072988
NOTE: The return type of this function is the POINTER type pointing
3008-
to the original flexible array type or the original pointer type.
3009-
Then the type of the INDIRECT_REF is the original flexible array type
3010-
or the original pointer type.
2989+
to the original flexible array type.
2990+
Then the type of the INDIRECT_REF is the original flexible array type.
2991+
2992+
The type of the first argument of this function is a POINTER type
2993+
to the original flexible array type.
30112994

30122995
The 4th argument of the call is a constant 0 with the TYPE of the
30132996
object pointed by COUNTED_BY_REF.
30142997

3015-
The 6th argument of the call is a constant 0 of the same TYPE as
3016-
the return type of the call.
2998+
The 6th argument of the call is a constant 0 with the pointer TYPE
2999+
to the original flexible array type.
30173000

30183001
*/
30193002
static tree
30203003
build_access_with_size_for_counted_by (location_t loc, tree ref,
30213004
tree counted_by_ref,
30223005
tree counted_by_type)
30233006
{
3024-
gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref))
3025-
|| TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE);
3026-
bool is_fam = c_flexible_array_member_type_p (TREE_TYPE (ref));
3027-
tree first_param = is_fam ? array_to_pointer_conversion (loc, ref)
3028-
: build_unary_op (loc, ADDR_EXPR, ref, false);
3029-
3030-
/* The result type of the call is a pointer to the original type
3031-
of the ref. */
3007+
gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)));
3008+
/* The result type of the call is a pointer to the flexible array type. */
30323009
tree result_type = c_build_pointer_type (TREE_TYPE (ref));
3033-
first_param = c_fully_fold (first_param, false, NULL);
3010+
tree first_param
3011+
= c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL);
30343012
tree second_param
30353013
= c_fully_fold (counted_by_ref, false, NULL);
30363014

@@ -3043,7 +3021,7 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
30433021
build_int_cst (counted_by_type, 0),
30443022
build_int_cst (integer_type_node, -1),
30453023
build_int_cst (result_type, 0));
3046-
/* Wrap the call with an INDIRECT_REF with the original type of the ref. */
3024+
/* Wrap the call with an INDIRECT_REF with the flexible array type. */
30473025
call = build1 (INDIRECT_REF, TREE_TYPE (ref), call);
30483026
SET_EXPR_LOCATION (call, loc);
30493027
return call;
@@ -3061,7 +3039,7 @@ handle_counted_by_for_component_ref (location_t loc, tree ref)
30613039
tree datum = TREE_OPERAND (ref, 0);
30623040
tree subdatum = TREE_OPERAND (ref, 1);
30633041
tree counted_by_type = NULL_TREE;
3064-
tree counted_by_ref = build_counted_by_ref (loc, datum, subdatum,
3042+
tree counted_by_ref = build_counted_by_ref (datum, subdatum,
30653043
&counted_by_type);
30663044
if (counted_by_ref)
30673045
ref = build_access_with_size_for_counted_by (loc, ref,

0 commit comments

Comments
 (0)