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

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.

	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.
This commit is contained in:
Qing Zhao 2025-04-14 19:41:12 +00:00
parent 99835bd68e
commit 727f330f9a
2 changed files with 30 additions and 2 deletions

View file

@ -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),

View file

@ -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;
}