diff options
author | Qing Zhao <qing.zhao@oracle.com> | 2025-08-14 20:27:20 +0000 |
---|---|---|
committer | Qing Zhao <qing.zhao@oracle.com> | 2025-08-15 15:28:10 +0000 |
commit | 1b34664c6255a7c1802e377be439f0d474dde0bb (patch) | |
tree | 92d2a909948fadba6d7104bc782d2385767edde3 | |
parent | 9e7f8568f751013266d2d1c4c0023ac7618f1b24 (diff) | |
download | gcc-1b34664c6255a7c1802e377be439f0d474dde0bb.zip gcc-1b34664c6255a7c1802e377be439f0d474dde0bb.tar.gz gcc-1b34664c6255a7c1802e377be439f0d474dde0bb.tar.bz2 |
Generate a call to a .ACCESS_WITH_SIZE for a FAM with counted_by attribute only when it's read from.
Currently, we generate a call to a .ACCESS_WITH_SIZE for a FAM with counted_by
attribute for every component_ref that corresponds to such an object.
Actually, such .ACCESS_WITH_SIZE calls are useless when they are generated
for a written site or an address taken site.
In this patch, we only generate a call to .ACCESS_WITH_SIZE for a FAM with
counted_by attribute when it's a read.
gcc/c/ChangeLog:
* c-tree.h (handle_counted_by_for_component_ref): New prototype of
build_component_ref and handle_counted_by_for_component_ref.
* c-parser.cc (c_parser_postfix_expression): Call the new prototypes
of build_component_ref and handle_counted_by_for_component_ref,
update comments.
* c-typeck.cc (default_function_array_read_conversion): Likewise.
(convert_lvalue_to_rvalue): Likewise.
(default_conversion): Likewise.
(handle_counted_by_p): Update comments.
(handle_counted_by_for_component_ref): Delete one argument.
(build_component_ref): Delete one argument. Delete the call to
handle_counted_by_for_component_ref completely.
(build_array_ref): Generate call to .ACCESS_WITH_SIZE for array.
gcc/testsuite/ChangeLog:
* gcc.dg/flex-array-counted-by-2.c: Adjust testing case.
-rw-r--r-- | gcc/c/c-parser.cc | 14 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 4 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 38 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/flex-array-counted-by-2.c | 2 |
4 files changed, 21 insertions, 37 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 148cd9a..510d727 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -11876,12 +11876,9 @@ c_parser_postfix_expression (c_parser *parser) if (c_parser_next_token_is (parser, CPP_NAME)) { c_token *comp_tok = c_parser_peek_token (parser); - /* Ignore the counted_by attribute for reference inside - offsetof since the information is not useful at all. */ offsetof_ref = build_component_ref (loc, offsetof_ref, comp_tok->value, - comp_tok->location, UNKNOWN_LOCATION, - false); + comp_tok->location, UNKNOWN_LOCATION); c_parser_consume_token (parser); while (c_parser_next_token_is (parser, CPP_DOT) || c_parser_next_token_is (parser, @@ -11908,14 +11905,11 @@ c_parser_postfix_expression (c_parser *parser) break; } c_token *comp_tok = c_parser_peek_token (parser); - /* Ignore the counted_by attribute for reference inside - offsetof since the information is not useful. */ offsetof_ref = build_component_ref (loc, offsetof_ref, comp_tok->value, comp_tok->location, - UNKNOWN_LOCATION, - false); + UNKNOWN_LOCATION); c_parser_consume_token (parser); } else @@ -12701,8 +12695,8 @@ c_parser_postfix_expression (c_parser *parser) /* If the array ref is inside TYPEOF or ALIGNOF, the call to .ACCESS_WITH_SIZE was not generated by the routine build_component_ref by default, we should generate it here. */ - if ((in_typeof || in_alignof) && TREE_CODE (ref) == COMPONENT_REF) - ref = handle_counted_by_for_component_ref (loc, ref, false); + if (TREE_CODE (ref) == COMPONENT_REF) + ref = handle_counted_by_for_component_ref (loc, ref); if (has_counted_by_object (ref)) expr.value = get_counted_by_ref (ref); diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index b8c81f6..afec03e2 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -821,8 +821,8 @@ extern void mark_exp_read (tree); extern tree composite_type (tree, tree); extern tree lookup_field (const_tree, tree); extern tree build_component_ref (location_t, tree, tree, location_t, - location_t, bool = true); -extern tree handle_counted_by_for_component_ref (location_t, tree, bool); + location_t); +extern tree handle_counted_by_for_component_ref (location_t, tree); extern tree build_array_ref (location_t, tree, tree); extern tree build_omp_array_section (location_t, tree, tree, tree); extern tree build_external_ref (location_t, tree, bool, tree *); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 9ea58e1..3c6f7d9 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -2487,11 +2487,10 @@ struct c_expr default_function_array_read_conversion (location_t loc, struct c_expr exp) { mark_exp_read (exp.value); - /* We only generate a call to .ACCESS_WITH_SIZE for a pointer field when - it is a read. */ + /* We only generate a call to .ACCESS_WITH_SIZE when it is a read. */ if (TREE_CODE (exp.value) == COMPONENT_REF && handle_counted_by_p (exp.value)) - exp.value = handle_counted_by_for_component_ref (loc, exp.value, true); + exp.value = handle_counted_by_for_component_ref (loc, exp.value); return default_function_array_conversion (loc, exp); } @@ -2593,11 +2592,10 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp, bool force_non_npc = false; if (read_p) mark_exp_read (exp.value); - /* We only generate a call to .ACCESS_WITH_SIZE for a pointer field when - it is a read. */ + /* We only generate a call to .ACCESS_WITH_SIZE when it is a read. */ if (read_p && TREE_CODE (exp.value) == COMPONENT_REF && handle_counted_by_p (exp.value)) - exp.value = handle_counted_by_for_component_ref (loc, exp.value, true); + exp.value = handle_counted_by_for_component_ref (loc, exp.value); if (convert_p) exp = default_function_array_conversion (loc, exp); @@ -2776,11 +2774,10 @@ default_conversion (tree exp) tree promoted_type; mark_exp_read (exp); - /* We only generate a call to .ACCESS_WITH_SIZE for a pointer field when - it is a read. */ + /* We only generate a call to .ACCESS_WITH_SIZE when it is a read. */ if (TREE_CODE (exp) == COMPONENT_REF && handle_counted_by_p (exp)) - exp = handle_counted_by_for_component_ref (EXPR_LOCATION (exp), exp, true); + exp = handle_counted_by_for_component_ref (EXPR_LOCATION (exp), exp); /* Functions and arrays have been converted during parsing. */ gcc_assert (code != FUNCTION_TYPE); @@ -3193,12 +3190,10 @@ build_access_with_size_for_counted_by (location_t loc, tree ref, /* For the COMPONENT_REF ref, check whether it has a counted_by attribute, if so, wrap this COMPONENT_REF with the corresponding CALL to the function .ACCESS_WITH_SIZE. - Otherwise, return the ref itself. - FOR_POINTER is true when this is for pointer field. */ + Otherwise, return the ref itself. */ tree -handle_counted_by_for_component_ref (location_t loc, tree ref, - bool for_pointer) +handle_counted_by_for_component_ref (location_t loc, tree ref) { gcc_assert (TREE_CODE (ref) == COMPONENT_REF); tree datum = TREE_OPERAND (ref, 0); @@ -3209,11 +3204,6 @@ handle_counted_by_for_component_ref (location_t loc, tree ref, || TREE_CODE (TREE_TYPE (ref)) == POINTER_TYPE)) return ref; - bool is_fam = c_flexible_array_member_type_p (TREE_TYPE (ref)); - - if (!(is_fam ^ for_pointer)) - return ref; - tree counted_by_ref = build_counted_by_ref (datum, subdatum, &counted_by_type); if (counted_by_ref) @@ -3233,8 +3223,7 @@ handle_counted_by_for_component_ref (location_t loc, tree ref, tree build_component_ref (location_t loc, tree datum, tree component, - location_t component_loc, location_t arrow_loc, - bool handle_counted_by) + location_t component_loc, location_t arrow_loc) { tree type = TREE_TYPE (datum); enum tree_code code = TREE_CODE (type); @@ -3306,8 +3295,6 @@ build_component_ref (location_t loc, tree datum, tree component, int quals; tree subtype; bool use_datum_quals; - /* Do not handle counted_by when in typeof and alignof operator. */ - handle_counted_by = handle_counted_by && !in_typeof && !in_alignof; if (TREE_TYPE (subdatum) == error_mark_node) return error_mark_node; @@ -3329,8 +3316,6 @@ build_component_ref (location_t loc, tree datum, tree component, SET_EXPR_LOCATION (ref, loc); check_counted_by_attribute (loc, ref); - if (handle_counted_by) - ref = handle_counted_by_for_component_ref (loc, ref, false); if (TREE_READONLY (subdatum) || (use_datum_quals && TREE_READONLY (datum))) @@ -3517,6 +3502,11 @@ build_array_ref (location_t loc, tree array, tree index) bool was_vector = VECTOR_TYPE_P (TREE_TYPE (array)); bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, index); + /* We only generate a call to .ACCESS_WITH_SIZE when it is a read. */ + if (TREE_CODE (array) == COMPONENT_REF + && handle_counted_by_p (array)) + array = handle_counted_by_for_component_ref (loc, array); + if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE) { tree rval, type; diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c index 42d6436..a9bec2d 100644 --- a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c @@ -111,4 +111,4 @@ int main(int argc, char *argv[]) return 0; } -/* { dg-final { scan-tree-dump-times "ACCESS_WITH_SIZE" 8 "original" } } */ +/* { dg-final { scan-tree-dump-times "ACCESS_WITH_SIZE" 6 "original" } } */ |