[v9,5/5] Add the 6th argument to .ACCESS_WITH_SIZE
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Testing passed
|
Commit Message
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.
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
Comments
On Fri, Apr 12, 2024 at 3:55 PM Qing Zhao <qing.zhao@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.
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
>
> On May 28, 2024, at 03:43, Richard Biener <richard.guenther@gmail.com> wrote:
>
> On Fri, Apr 12, 2024 at 3:55 PM Qing Zhao <qing.zhao@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? -:)
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
>>
On Tue, May 28, 2024 at 11:10 PM Qing Zhao <qing.zhao@oracle.com> wrote:
>
>
>
> > On May 28, 2024, at 03:43, Richard Biener <richard.guenther@gmail.com> wrote:
> >
> > On Fri, Apr 12, 2024 at 3:55 PM Qing Zhao <qing.zhao@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
> >>
>
@@ -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);
@@ -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
new file mode 100644
@@ -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;
+}
@@ -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));