to:
(*.ACCESS_WITH_SIZE (REF, COUNTED_BY_REF, 1, (TYPE_OF_SIZE)0, -1,
- (TYPE_OF_ARRAY *)0))
+ TYPE_SIZE_UNIT for element)
NOTE: The return type of this function is the POINTER type pointing
to the original flexible array 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.
+ The 6th argument of the call is the TYPE_SIZE_UNIT of the element TYPE
+ of the FAM.
*/
static tree
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 element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
+
tree first_param
= c_fully_fold (array_to_pointer_conversion (loc, ref), false, NULL);
tree second_param
build_int_cst (integer_type_node, 1),
build_int_cst (counted_by_type, 0),
build_int_cst (integer_type_node, -1),
- build_int_cst (result_type, 0));
+ element_size);
/* 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);
/* Expand the IFN_ACCESS_WITH_SIZE function:
ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE, CLASS_OF_SIZE,
- TYPE_OF_SIZE, ACCESS_MODE)
+ TYPE_OF_SIZE, ACCESS_MODE, TYPE_SIZE_UNIT for element)
which returns the REF_TO_OBJ same as the 1st argument;
1st argument REF_TO_OBJ: The reference to the object;
3rd argument CLASS_OF_SIZE: The size referenced by the REF_TO_SIZE represents
0: the number of bytes.
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
+ 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
5th argument ACCESS_MODE:
-1: Unknown access semantics
0: none
1: read_only
2: write_only
3: read_write
- 6th argument: A constant 0 with the pointer TYPE to the original flexible
- array type.
+ 6th argument: The TYPE_SIZE_UNIT of the element TYPE of the FAM when the
+ 3rd argument is 1; NULL when the 3rd argument is 0.
Both the return type and the type of the first argument of this
function have been converted from the incomplete array type to
/* A function to associate the access size and access mode information
with the corresponding reference to an object. It only reads from the
- 2nd argument. */
+ 2nd and the 6th arguments. */
DEF_INTERNAL_FN (ACCESS_WITH_SIZE, ECF_PURE | ECF_LEAF | ECF_NOTHROW, NULL)
/* DIM_SIZE and DIM_POS return the size of a particular compute
--- /dev/null
+/* PR middle-end/121000 */
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+#include "builtin-object-size-common.h"
+
+/* The parameter m must be const qualified to avoid the m is
+ marked as TREE_SIDE_EFFECTS in IR.
+ The __builtin_dynamic_object_size will be folded as -1 by
+ fold_builtin_object_size when m is NOT const qualified. */
+
+void
+foo (int n, const int m)
+{
+ typedef int A[m];
+ struct S { int n, m; A a[2]; A b[] __attribute__((counted_by (n))); } *p;
+ p = __builtin_malloc (sizeof (struct S) + sizeof (A) * n);
+ p->n = n;
+ p->m = m;
+ EXPECT (__builtin_dynamic_object_size (p->b, 1), sizeof (A) * n);
+}
+
+/* The parameter m1, m2 must be const qualified to avoid the m is
+ marked as TREE_SIDE_EFFECTS in IR.
+ The __builtin_dynamic_object_size will be folded as -1 by
+ fold_builtin_object_size when m1 or m2 is NOT const qualified. */
+void
+foo_1 (int n, const int m1, const int m2)
+{
+ typedef int A[m1][m2];
+ struct S { int n; A a[2]; A b[] __attribute__((counted_by (n))); } *p;
+ p = __builtin_malloc (sizeof (struct S) + sizeof (A) * n);
+ p->n = n;
+ EXPECT (__builtin_dynamic_object_size (p->b, 1), sizeof (A) * n);
+}
+
+int
+main ()
+{
+ foo (2, 10);
+ foo_1 (2, 10, 20);
+ return 0;
+}
/* Compute __builtin_object_size for a CALL to .ACCESS_WITH_SIZE,
OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
- The 2nd, 3rd, and the 4th parameters of the call determine the size of
+
+ The 2nd, 3rd, 4th and 6th parameters of the call determine the size of
the CALL:
2nd argument REF_TO_SIZE: The reference to the size of the object,
3rd argument CLASS_OF_SIZE: The size referenced by the REF_TO_SIZE represents
0: the number of bytes;
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.
+ 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: The TYPE_SIZE_UNIT of the element TYPE of the FAM when the
+ 3rd argument is 1; NULL when the 3rd argument is 0. */
- 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)
{
/* If not for dynamic object size, return. */
if ((object_size_type & OST_DYNAMIC) == 0)
return size_unknown (object_size_type);
-
gcc_assert (gimple_call_internal_p (call, IFN_ACCESS_WITH_SIZE));
- /* 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));
+ /* The 6th argument is the TYPE_SIZE_UNIT for the element of the original
+ flexible array. */
+ tree element_size = gimple_call_arg (call, 5);
+
+ gcc_assert ((class_of_size == 1 && element_size)
+ || (class_of_size == 0 && !element_size));
+
tree size = fold_build2 (MEM_REF, type, ref_to_size,
build_int_cst (ptr_type_node, 0));