c: Fully fold each parameter for call to .ACCESS_WITH_SIZE [PR119717]

Message ID 20250414202855.176269-1-qing.zhao@oracle.com
State New
Headers
Series c: Fully fold each parameter for call to .ACCESS_WITH_SIZE [PR119717] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed

Commit Message

Qing Zhao April 14, 2025, 8:28 p.m. UTC
  C_MAYBE_CONST_EXPR is a C FE operator that will be removed by c_fully_fold.
In c_fully_fold, it assumes that operands of function calls have already
been folded. However, when we build call to .ACCESS_WITH_SIZE, all its
operands are not fully folded. therefore the C FE specific operator is
passed to middle-end.

In order to fix this issue, fully fold the parameters before building the
call to .ACCESS_WITH_SIZE.

I am doing the bootstrap and regression testing on both X86 and aarch64 now.
Okay for trunk if testing going well?

thanks.

Qing

	PR c/119717

gcc/c/ChangeLog:

	* c-typeck.cc (build_access_with_size_for_counted_by): Fully fold the
	parameters for call to .ACCESS_WITH_SIZE.

gcc/testsuite/ChangeLog:

	* gcc.dg/pr119717.c: New test.
---
 gcc/c/c-typeck.cc               |  8 ++++++--
 gcc/testsuite/gcc.dg/pr119717.c | 24 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr119717.c
  

Comments

Marek Polacek April 14, 2025, 8:35 p.m. UTC | #1
On Mon, Apr 14, 2025 at 08:28:55PM +0000, Qing Zhao wrote:
> C_MAYBE_CONST_EXPR is a C FE operator that will be removed by c_fully_fold.
> In c_fully_fold, it assumes that operands of function calls have already
> been folded. However, when we build call to .ACCESS_WITH_SIZE, all its
> operands are not fully folded. therefore the C FE specific operator is
> passed to middle-end.
> 
> In order to fix this issue, fully fold the parameters before building the
> call to .ACCESS_WITH_SIZE.
> 
> I am doing the bootstrap and regression testing on both X86 and aarch64 now.
> Okay for trunk if testing going well?
> 
> thanks.
> 
> Qing
> 
> 	PR c/119717
> 
> gcc/c/ChangeLog:
> 
> 	* c-typeck.cc (build_access_with_size_for_counted_by): Fully fold the
> 	parameters for call to .ACCESS_WITH_SIZE.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.dg/pr119717.c: New test.
> ---
>  gcc/c/c-typeck.cc               |  8 ++++++--
>  gcc/testsuite/gcc.dg/pr119717.c | 24 ++++++++++++++++++++++++
>  2 files changed, 30 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr119717.c
> 
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 3870e8a1558..dd176d96a41 100644
> --- a/gcc/c/c-typeck.cc
> +++ b/gcc/c/c-typeck.cc
> @@ -3013,12 +3013,16 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
>    gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)));
>    /* The result type of the call is a pointer to the flexible array type.  */
>    tree result_type = c_build_pointer_type (TREE_TYPE (ref));
> +  tree first_param
> +    = c_fully_fold (array_to_pointer_conversion (loc, ref), FALSE, NULL);
> +  tree second_param
> +    = c_fully_fold (counted_by_ref, FALSE, NULL);

Why FALSE?  Just use false.  You can also use nullptr rather than NULL now.
  
>    tree call
>      = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE,
>  				    result_type, 6,
> -				    array_to_pointer_conversion (loc, ref),
> -				    counted_by_ref,
> +				    first_param,
> +				    second_param,
>  				    build_int_cst (integer_type_node, 1),
>  				    build_int_cst (counted_by_type, 0),
>  				    build_int_cst (integer_type_node, -1),
> diff --git a/gcc/testsuite/gcc.dg/pr119717.c b/gcc/testsuite/gcc.dg/pr119717.c
> new file mode 100644
> index 00000000000..e5eedc567b3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr119717.c
> @@ -0,0 +1,24 @@
> +/* PR c/119717  */
> +/* { dg-additional-options "-std=c23" } */
> +/* { dg-do compile } */
> +
> +struct annotated {
> +  unsigned count;
> +  [[gnu::counted_by(count)]] char array[];
> +};
> +
> +[[gnu::noinline,gnu::noipa]]
> +static unsigned
> +size_of (bool x, struct annotated *a)
> +{
> +  char *p = (x ? a : 0)->array;
> +  return __builtin_dynamic_object_size (p, 1);
> +}
> +
> +int main()
> +{
> +  struct annotated *p = __builtin_malloc(sizeof *p);
> +  p->count = 0;
> +  __builtin_printf ("the bdos whole is %ld\n", size_of (0, p));
> +  return 0;
> +}
> -- 
> 2.31.1
> 

Marek
  
Qing Zhao April 14, 2025, 8:41 p.m. UTC | #2
> On Apr 14, 2025, at 16:35, Marek Polacek <polacek@redhat.com> wrote:
> 
> On Mon, Apr 14, 2025 at 08:28:55PM +0000, Qing Zhao wrote:
>> C_MAYBE_CONST_EXPR is a C FE operator that will be removed by c_fully_fold.
>> In c_fully_fold, it assumes that operands of function calls have already
>> been folded. However, when we build call to .ACCESS_WITH_SIZE, all its
>> operands are not fully folded. therefore the C FE specific operator is
>> passed to middle-end.
>> 
>> In order to fix this issue, fully fold the parameters before building the
>> call to .ACCESS_WITH_SIZE.
>> 
>> I am doing the bootstrap and regression testing on both X86 and aarch64 now.
>> Okay for trunk if testing going well?
>> 
>> thanks.
>> 
>> Qing
>> 
>> PR c/119717
>> 
>> gcc/c/ChangeLog:
>> 
>> * c-typeck.cc (build_access_with_size_for_counted_by): Fully fold the
>> parameters for call to .ACCESS_WITH_SIZE.
>> 
>> gcc/testsuite/ChangeLog:
>> 
>> * gcc.dg/pr119717.c: New test.
>> ---
>> gcc/c/c-typeck.cc               |  8 ++++++--
>> gcc/testsuite/gcc.dg/pr119717.c | 24 ++++++++++++++++++++++++
>> 2 files changed, 30 insertions(+), 2 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.dg/pr119717.c
>> 
>> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
>> index 3870e8a1558..dd176d96a41 100644
>> --- a/gcc/c/c-typeck.cc
>> +++ b/gcc/c/c-typeck.cc
>> @@ -3013,12 +3013,16 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
>>   gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)));
>>   /* The result type of the call is a pointer to the flexible array type.  */
>>   tree result_type = c_build_pointer_type (TREE_TYPE (ref));
>> +  tree first_param
>> +    = c_fully_fold (array_to_pointer_conversion (loc, ref), FALSE, NULL);
>> +  tree second_param
>> +    = c_fully_fold (counted_by_ref, FALSE, NULL);
> 
> Why FALSE?  Just use false.  You can also use nullptr rather than NULL now.

Just replaced FALSE with false.
I am keeping NULL to be consistent with other calls to c_fully_fold in the same file.

And  testing the new version now.

Thanks a lot.

(With FALSE, the compilation went fine…)

Qing
> 
>>   tree call
>>     = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE,
>>     result_type, 6,
>> -     array_to_pointer_conversion (loc, ref),
>> -     counted_by_ref,
>> +     first_param,
>> +     second_param,
>>     build_int_cst (integer_type_node, 1),
>>     build_int_cst (counted_by_type, 0),
>>     build_int_cst (integer_type_node, -1),
>> diff --git a/gcc/testsuite/gcc.dg/pr119717.c b/gcc/testsuite/gcc.dg/pr119717.c
>> new file mode 100644
>> index 00000000000..e5eedc567b3
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pr119717.c
>> @@ -0,0 +1,24 @@
>> +/* PR c/119717  */
>> +/* { dg-additional-options "-std=c23" } */
>> +/* { dg-do compile } */
>> +
>> +struct annotated {
>> +  unsigned count;
>> +  [[gnu::counted_by(count)]] char array[];
>> +};
>> +
>> +[[gnu::noinline,gnu::noipa]]
>> +static unsigned
>> +size_of (bool x, struct annotated *a)
>> +{
>> +  char *p = (x ? a : 0)->array;
>> +  return __builtin_dynamic_object_size (p, 1);
>> +}
>> +
>> +int main()
>> +{
>> +  struct annotated *p = __builtin_malloc(sizeof *p);
>> +  p->count = 0;
>> +  __builtin_printf ("the bdos whole is %ld\n", size_of (0, p));
>> +  return 0;
>> +}
>> -- 
>> 2.31.1
>> 
> 
> Marek
  

Patch

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 3870e8a1558..dd176d96a41 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -3013,12 +3013,16 @@  build_access_with_size_for_counted_by (location_t loc, tree ref,
   gcc_assert (c_flexible_array_member_type_p (TREE_TYPE (ref)));
   /* The result type of the call is a pointer to the flexible array type.  */
   tree result_type = c_build_pointer_type (TREE_TYPE (ref));
+  tree first_param
+    = c_fully_fold (array_to_pointer_conversion (loc, ref), FALSE, NULL);
+  tree second_param
+    = c_fully_fold (counted_by_ref, FALSE, NULL);
 
   tree call
     = build_call_expr_internal_loc (loc, IFN_ACCESS_WITH_SIZE,
 				    result_type, 6,
-				    array_to_pointer_conversion (loc, ref),
-				    counted_by_ref,
+				    first_param,
+				    second_param,
 				    build_int_cst (integer_type_node, 1),
 				    build_int_cst (counted_by_type, 0),
 				    build_int_cst (integer_type_node, -1),
diff --git a/gcc/testsuite/gcc.dg/pr119717.c b/gcc/testsuite/gcc.dg/pr119717.c
new file mode 100644
index 00000000000..e5eedc567b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119717.c
@@ -0,0 +1,24 @@ 
+/* PR c/119717  */
+/* { dg-additional-options "-std=c23" } */
+/* { dg-do compile } */
+
+struct annotated {
+  unsigned count;
+  [[gnu::counted_by(count)]] char array[];
+};
+
+[[gnu::noinline,gnu::noipa]]
+static unsigned
+size_of (bool x, struct annotated *a)
+{
+  char *p = (x ? a : 0)->array;
+  return __builtin_dynamic_object_size (p, 1);
+}
+
+int main()
+{
+  struct annotated *p = __builtin_malloc(sizeof *p);
+  p->count = 0;
+  __builtin_printf ("the bdos whole is %ld\n", size_of (0, p));
+  return 0;
+}