On Tue, May 28, 2024 at 11:10 PM Qing Zhao <qing.z...@oracle.com> wrote: > > > > > On May 28, 2024, at 03:43, Richard Biener <richard.guent...@gmail.com> > > wrote: > > > > On Fri, Apr 12, 2024 at 3:55 PM Qing Zhao <qing.z...@oracle.com> wrote: > >> > >> to carry the TYPE of the flexible array. > >> > >> Such information is needed during tree-object-size.cc. > >> > >> We cannot use the result type or the type of the 1st argument > >> of the routine .ACCESS_WITH_SIZE to decide the element type > >> of the original array due to possible type casting in the > >> source code. > > > > OK. I guess technically an empty CONSTRUCTOR of the array type > > would work as well (as aggregate it's fine to have it in the call) but a > > constant zero pointer might be cheaper to have as it's shared across > > multiple calls. > > So, I consider this as an approval? -:)
yes > thanks. > > Qing > > > > Richard. > > > >> gcc/c/ChangeLog: > >> > >> * c-typeck.cc (build_access_with_size_for_counted_by): Add the 6th > >> argument to .ACCESS_WITH_SIZE. > >> > >> gcc/ChangeLog: > >> > >> * tree-object-size.cc (access_with_size_object_size): Use the type > >> of the 6th argument for the type of the element. > >> > >> gcc/testsuite/ChangeLog: > >> > >> * gcc.dg/flex-array-counted-by-6.c: New test. > >> --- > >> gcc/c/c-typeck.cc | 11 +++-- > >> gcc/internal-fn.cc | 2 + > >> .../gcc.dg/flex-array-counted-by-6.c | 46 +++++++++++++++++++ > >> gcc/tree-object-size.cc | 16 ++++--- > >> 4 files changed, 66 insertions(+), 9 deletions(-) > >> create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-6.c > >> > >> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc > >> index ff6685c6c4ba..0ea3b75355a4 100644 > >> --- a/gcc/c/c-typeck.cc > >> +++ b/gcc/c/c-typeck.cc > >> @@ -2640,7 +2640,8 @@ build_counted_by_ref (tree datum, tree subdatum, > >> tree *counted_by_type) > >> > >> to: > >> > >> - (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, (TYPE_OF_SIZE)0, -1)) > >> + (*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, (TYPE_OF_SIZE)0, -1, > >> + (TYPE_OF_ARRAY *)0)) > >> > >> NOTE: The return type of this function is the POINTER type pointing > >> to the original flexible array type. > >> @@ -2652,6 +2653,9 @@ build_counted_by_ref (tree datum, tree subdatum, > >> tree *counted_by_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 with the pointer TYPE > >> + to the original flexible array type. > >> + > >> */ > >> static tree > >> build_access_with_size_for_counted_by (location_t loc, tree ref, > >> @@ -2664,12 +2668,13 @@ build_access_with_size_for_counted_by (location_t > >> loc, tree ref, > >> > >> tree call > >> = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE, > >> - result_type, 5, > >> + result_type, 6, > >> array_to_pointer_conversion (loc, ref), > >> counted_by_ref, > >> build_int_cst (integer_type_node, 1), > >> build_int_cst (counted_by_type, 0), > >> - build_int_cst (integer_type_node, -1)); > >> + build_int_cst (integer_type_node, -1), > >> + build_int_cst (result_type, 0)); > >> /* 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); > >> diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc > >> index e744080ee670..34e4a4aea534 100644 > >> --- a/gcc/internal-fn.cc > >> +++ b/gcc/internal-fn.cc > >> @@ -3411,6 +3411,8 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt) > >> 1: read_only > >> 2: write_only > >> 3: read_write > >> + 6th argument: A constant 0 with the pointer TYPE to the original > >> flexible > >> + array type. > >> > >> Both the return type and the type of the first argument of this > >> function have been converted from the incomplete array type to > >> diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-6.c > >> b/gcc/testsuite/gcc.dg/flex-array-counted-by-6.c > >> new file mode 100644 > >> index 000000000000..65fa01443d95 > >> --- /dev/null > >> +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-6.c > >> @@ -0,0 +1,46 @@ > >> +/* Test the attribute counted_by and its usage in > >> + * __builtin_dynamic_object_size: when the type of the flexible array > >> member > >> + * is casting to another type. */ > >> +/* { dg-do run } */ > >> +/* { dg-options "-O2" } */ > >> + > >> +#include "builtin-object-size-common.h" > >> + > >> +typedef unsigned short u16; > >> + > >> +struct info { > >> + u16 data_len; > >> + char data[] __attribute__((counted_by(data_len))); > >> +}; > >> + > >> +struct foo { > >> + int a; > >> + int b; > >> +}; > >> + > >> +static __attribute__((__noinline__)) > >> +struct info *setup () > >> +{ > >> + struct info *p; > >> + size_t bytes = 3 * sizeof(struct foo); > >> + > >> + p = (struct info *)malloc (sizeof (struct info) + bytes); > >> + p->data_len = bytes; > >> + > >> + return p; > >> +} > >> + > >> +static void > >> +__attribute__((__noinline__)) report (struct info *p) > >> +{ > >> + struct foo *bar = (struct foo *)p->data; > >> + EXPECT(__builtin_dynamic_object_size((char *)(bar + 1), 1), 16); > >> + EXPECT(__builtin_dynamic_object_size((char *)(bar + 2), 1), 8); > >> +} > >> + > >> +int main(int argc, char *argv[]) > >> +{ > >> + struct info *p = setup(); > >> + report(p); > >> + return 0; > >> +} > >> diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc > >> index 8de264d1dee2..4c1fa9b555fa 100644 > >> --- a/gcc/tree-object-size.cc > >> +++ b/gcc/tree-object-size.cc > >> @@ -762,9 +762,11 @@ addr_object_size (struct object_size_info *osi, > >> const_tree ptr, > >> 1: the number of the elements of the object type; > >> 4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as > >> the TYPE > >> of the object referenced by REF_TO_SIZE > >> + 6th argument: A constant 0 with the pointer TYPE to the original > >> flexible > >> + array type. > >> > >> - The size of the element can be retrived from the result type of the > >> call, > >> - which is the pointer to the array type. */ > >> + The size of the element can be retrived from the TYPE of the 6th > >> argument > >> + of the call, which is the pointer to the array type. */ > >> static tree > >> access_with_size_object_size (const gcall *call, int object_size_type) > >> { > >> @@ -773,10 +775,12 @@ access_with_size_object_size (const gcall *call, int > >> object_size_type) > >> return size_unknown (object_size_type); > >> > >> gcc_assert (gimple_call_internal_p (call, IFN_ACCESS_WITH_SIZE)); > >> - /* Result type is a pointer type to the original flexible array type. > >> */ > >> - tree result_type = gimple_call_return_type (call); > >> - gcc_assert (POINTER_TYPE_P (result_type)); > >> - tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE > >> (result_type))); > >> + /* The type of the 6th argument type is the pointer TYPE to the original > >> + flexible array type. */ > >> + tree pointer_to_array_type = TREE_TYPE (gimple_call_arg (call, 5)); > >> + gcc_assert (POINTER_TYPE_P (pointer_to_array_type)); > >> + tree element_type = TREE_TYPE (TREE_TYPE (pointer_to_array_type)); > >> + tree element_size = TYPE_SIZE_UNIT (element_type); > >> tree ref_to_size = gimple_call_arg (call, 1); > >> unsigned int class_of_size = TREE_INT_CST_LOW (gimple_call_arg (call, > >> 2)); > >> tree type = TREE_TYPE (gimple_call_arg (call, 3)); > >> -- > >> 2.31.1 > >> >