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
> >>
>

Reply via email to