aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQing Zhao <qing.zhao@oracle.com>2025-04-14 19:41:12 +0000
committerQing Zhao <qing.zhao@oracle.com>2025-04-15 20:38:17 +0000
commit727f330f9ac661339af1121fc5c9b67dd0d35872 (patch)
treec0b708fb5d601d81d8f26acd614ace9fc800e6cf
parent99835bd68e5360b0b3c8ad9c61ea23f70ad3dce6 (diff)
downloadgcc-727f330f9ac661339af1121fc5c9b67dd0d35872.zip
gcc-727f330f9ac661339af1121fc5c9b67dd0d35872.tar.gz
gcc-727f330f9ac661339af1121fc5c9b67dd0d35872.tar.bz2
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.
-rw-r--r--gcc/c/c-typeck.cc8
-rw-r--r--gcc/testsuite/gcc.dg/pr119717.c24
2 files changed, 30 insertions, 2 deletions
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 3870e8a..55d896e 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 0000000..e5eedc5
--- /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;
+}