This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] __builtin_object_size improvements (take 2)


On Mon, Jun 8, 2009 at 9:48 AM, Jakub Jelinek<jakub@redhat.com> wrote:
> On Fri, Jun 05, 2009 at 10:46:45PM +0200, Richard Guenther wrote:
>> > struct A { char a[10]; char b; } *p;
>> > shouldn't allow strcpy (&p->b, "abc");
>>
>> Correct.
>>
>> > Not sure about:
>> > struct B { int i; struct A { char b; char a[10]; } j; } *p;
>> > strcpy (&p->j.a[3], "abcdefghijklmnop");
>> > (in this case there is array as last field in struct A, but struct A itself
>> > is not in array).
>>
>> Unless struct A is wrapped inside a union and that union is the outermost
>> thing this would be also disallowed. ?(yes we have that case in GCC ...,
>> luckily not with chars)
>>
>> > Or:
>> > struct B { int i; struct A { char b; char a[10]; } j[1]; } *p;
>> > strcpy (&p->j[0].a[3], "abcdefghijklmnop");
>> > In this case both last fields involved are arrays, but still if
>> > the outer array were to be treated as "flexible", it would cross different
>> > fields, so I'd say we should disallow this too.
>>
>> Right. ?Only outermost (with the exception of union wrapping) trailing
>> arrays should be treated flexible.
>
> Here is an updated patch which adds testcases for the cases we were
> discussing and modifies the code to make them all pass.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2009-06-08 ?Jakub Jelinek ?<jakub@redhat.com>
>
> ? ? ? ?* tree-object-size.c (addr_object_size): Add OSI argument.
> ? ? ? ?Handle also INDIRECT_REF with SSA_NAME inside of it as base address.
> ? ? ? ?(compute_builtin_object_size, expr_object_size): Adjust callers.
> ? ? ? ?(plus_stmt_object_size): Call addr_object_size instead of
> ? ? ? ?compute_builtin_object_size.
>
> ? ? ? ?* gcc.dg/builtin-object-size-2.c (test1): Adjust expected results.
> ? ? ? ?* gcc.dg/builtin-object-size-4.c (test1): Adjust expected results.
> ? ? ? ?* gcc.dg/builtin-object-size-6.c: New test.
>
> --- gcc/tree-object-size.c.jj ? 2009-06-08 11:53:41.000000000 +0200
> +++ gcc/tree-object-size.c ? ? ?2009-06-08 13:56:23.000000000 +0200
> @@ -43,7 +43,8 @@ struct object_size_info
> ?static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
>
> ?static tree compute_object_offset (const_tree, const_tree);
> -static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
> +static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const_tree, int);
> ?static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
> ?static tree pass_through_call (const_gimple);
> ?static void collect_object_sizes_for (struct object_size_info *, tree);
> @@ -152,9 +153,10 @@ compute_object_offset (const_tree expr,
> ? ?If unknown, return unknown[object_size_type]. ?*/
>
> ?static unsigned HOST_WIDE_INT
> -addr_object_size (const_tree ptr, int object_size_type)
> +addr_object_size (struct object_size_info *osi, const_tree ptr,
> + ? ? ? ? ? ? ? ? int object_size_type)
> ?{
> - ?tree pt_var;
> + ?tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
>
> ? gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
>
> @@ -163,58 +165,170 @@ addr_object_size (const_tree ptr, int ob
> ? ? pt_var = get_base_address (pt_var);
>
> ? if (pt_var
> - ? ? ?&& (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
> - ? ? ?&& TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
> - ? ? ?&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
> - ? ? ?&& (unsigned HOST_WIDE_INT)
> - ? ? ? ?tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1) < offset_limit)
> + ? ? ?&& TREE_CODE (pt_var) == INDIRECT_REF
> + ? ? ?&& TREE_CODE (TREE_OPERAND (pt_var, 0)) == SSA_NAME
> + ? ? ?&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (pt_var, 0))))
> + ? ?{
> + ? ? ?unsigned HOST_WIDE_INT sz;
> +
> + ? ? ?if (!osi)
> + ? ? ? sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? object_size_type);
> + ? ? ?else
> + ? ? ? {
> + ? ? ? ? tree var = TREE_OPERAND (pt_var, 0);
> + ? ? ? ? if (osi->pass == 0)
> + ? ? ? ? ? collect_object_sizes_for (osi, var);
> + ? ? ? ? if (bitmap_bit_p (computed[object_size_type],
> + ? ? ? ? ? ? ? ? ? ? ? ? ? SSA_NAME_VERSION (var)))
> + ? ? ? ? ? sz = object_sizes[object_size_type][SSA_NAME_VERSION (var)];
> + ? ? ? ? else
> + ? ? ? ? ? sz = unknown[object_size_type];
> + ? ? ? }
> +
> + ? ? ?if (sz != unknown[object_size_type] && sz < offset_limit)
> + ? ? ? pt_var_size = size_int (sz);
> + ? ?}
> + ?else if (pt_var
> + ? ? ? ? ?&& (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
> + ? ? ? ? ?&& TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
> + ? ? ? ? ?&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
> + ? ? ? ? ?&& (unsigned HOST_WIDE_INT)
> + ? ? ? ? ? ? tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
> + ? ? ? ? ? ? < offset_limit)
> + ? ?pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
> + ?else
> + ? ?return unknown[object_size_type];
> +
> + ?if (pt_var != TREE_OPERAND (ptr, 0))
> ? ? {
> - ? ? ?tree bytes;
> + ? ? ?tree var;
>
> - ? ? ?if (pt_var != TREE_OPERAND (ptr, 0))
> + ? ? ?if (object_size_type & 1)
> ? ? ? ?{
> - ? ? ? ? tree var;
> + ? ? ? ? var = TREE_OPERAND (ptr, 0);
>
> - ? ? ? ? if (object_size_type & 1)
> + ? ? ? ? while (var != pt_var
> + ? ? ? ? ? ? ? ?&& TREE_CODE (var) != BIT_FIELD_REF
> + ? ? ? ? ? ? ? ?&& TREE_CODE (var) != COMPONENT_REF
> + ? ? ? ? ? ? ? ?&& TREE_CODE (var) != ARRAY_REF
> + ? ? ? ? ? ? ? ?&& TREE_CODE (var) != ARRAY_RANGE_REF
> + ? ? ? ? ? ? ? ?&& TREE_CODE (var) != REALPART_EXPR
> + ? ? ? ? ? ? ? ?&& TREE_CODE (var) != IMAGPART_EXPR)
> + ? ? ? ? ? var = TREE_OPERAND (var, 0);
> + ? ? ? ? if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
> + ? ? ? ? ? ? var = TREE_OPERAND (var, 0);
> + ? ? ? ? if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
> + ? ? ? ? ? ? || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
> + ? ? ? ? ? ? || (pt_var_size
> + ? ? ? ? ? ? ? ? && tree_int_cst_lt (pt_var_size,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE_SIZE_UNIT (TREE_TYPE (var)))))
> + ? ? ? ? ? var = pt_var;
> + ? ? ? ? else if (var != pt_var && TREE_CODE (pt_var) == INDIRECT_REF)
> ? ? ? ? ? ?{
> - ? ? ? ? ? ? var = TREE_OPERAND (ptr, 0);
> -
> - ? ? ? ? ? ? while (var != pt_var
> - ? ? ? ? ? ? ? ? ? ? && TREE_CODE (var) != BIT_FIELD_REF
> - ? ? ? ? ? ? ? ? ? ? && TREE_CODE (var) != COMPONENT_REF
> - ? ? ? ? ? ? ? ? ? ? && TREE_CODE (var) != ARRAY_REF
> - ? ? ? ? ? ? ? ? ? ? && TREE_CODE (var) != ARRAY_RANGE_REF
> - ? ? ? ? ? ? ? ? ? ? && TREE_CODE (var) != REALPART_EXPR
> - ? ? ? ? ? ? ? ? ? ? && TREE_CODE (var) != IMAGPART_EXPR)
> - ? ? ? ? ? ? ? var = TREE_OPERAND (var, 0);
> - ? ? ? ? ? ? if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
> - ? ? ? ? ? ? ? var = TREE_OPERAND (var, 0);
> - ? ? ? ? ? ? if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
> - ? ? ? ? ? ? ? ? || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
> - ? ? ? ? ? ? ? ? || tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)),
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE_SIZE_UNIT (TREE_TYPE (var))))
> + ? ? ? ? ? ? tree v = var;
> + ? ? ? ? ? ? /* For &X->fld, compute object size only if fld isn't the last
> + ? ? ? ? ? ? ? ?field, as struct { int i; char c[1]; } is often used instead
> + ? ? ? ? ? ? ? ?of flexible array member. ?*/
> + ? ? ? ? ? ? while (v && v != pt_var)
> + ? ? ? ? ? ? ? switch (TREE_CODE (v))
> + ? ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? case ARRAY_REF:
> + ? ? ? ? ? ? ? ? ? if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0)))
> + ? ? ? ? ? ? ? ? ? ? ? && TREE_CODE (TREE_OPERAND (v, 1)) == INTEGER_CST)
> + ? ? ? ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? ? ? ? tree domain
> + ? ? ? ? ? ? ? ? ? ? ? ? = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
> + ? ? ? ? ? ? ? ? ? ? ? if (domain
> + ? ? ? ? ? ? ? ? ? ? ? ? ? && TYPE_MAX_VALUE (domain)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? && TREE_CODE (TYPE_MAX_VALUE (domain))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?== INTEGER_CST
> + ? ? ? ? ? ? ? ? ? ? ? ? ? && tree_int_cst_lt (TREE_OPERAND (v, 1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE_MAX_VALUE (domain)))
> + ? ? ? ? ? ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? v = NULL_TREE;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? v = TREE_OPERAND (v, 0);
> + ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? case REALPART_EXPR:
> + ? ? ? ? ? ? ? ? case IMAGPART_EXPR:
> + ? ? ? ? ? ? ? ? ? v = NULL_TREE;
> + ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? case COMPONENT_REF:
> + ? ? ? ? ? ? ? ? ? if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> + ? ? ? ? ? ? ? ? ? ? ? ?== RECORD_TYPE
> + ? ? ? ? ? ? ? ? ? ? ? ?&& TREE_CHAIN (TREE_OPERAND (v, 1)))
> + ? ? ? ? ? ? ? ? ? ? ? || TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
> + ? ? ? ? ? ? ? ? ? ? v = NULL_TREE;
> + ? ? ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? ? ? ? if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
> + ? ? ? ? ? ? ? ? ? ? ? ? ? == RECORD_TYPE)
> + ? ? ? ? ? ? ? ? ? ? ? ? v = TREE_OPERAND (v, 0);
> + ? ? ? ? ? ? ? ? ? ? ? while (v && v != pt_var && TREE_CODE (v) == COMPONENT_REF)
> + ? ? ? ? ? ? ? ? ? ? ? ? if (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? && TREE_CODE (TREE_TYPE (v)) != QUAL_UNION_TYPE)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? ? ? v = TREE_OPERAND (v, 0);
> + ? ? ? ? ? ? ? ? ? ? ? if (v && v != pt_var)
> + ? ? ? ? ? ? ? ? ? ? ? ? v = NULL_TREE;
> + ? ? ? ? ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? ? v = pt_var;
> + ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? default:
> + ? ? ? ? ? ? ? ? ? v = pt_var;
> + ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? if (v == pt_var)
> ? ? ? ? ? ? ? ?var = pt_var;
> ? ? ? ? ? ?}
> - ? ? ? ? else
> - ? ? ? ? ? var = pt_var;
> + ? ? ? }
> + ? ? ?else
> + ? ? ? var = pt_var;
>
> - ? ? ? ? bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
> - ? ? ? ? if (bytes != error_mark_node)
> + ? ? ?if (var != pt_var)
> + ? ? ? var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
> + ? ? ?else if (!pt_var_size)
> + ? ? ? return unknown[object_size_type];
> + ? ? ?else
> + ? ? ? var_size = pt_var_size;
> + ? ? ?bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
> + ? ? ?if (bytes != error_mark_node)
> + ? ? ? {
> + ? ? ? ? if (TREE_CODE (bytes) == INTEGER_CST
> + ? ? ? ? ? ? && tree_int_cst_lt (var_size, bytes))
> + ? ? ? ? ? bytes = size_zero_node;
> + ? ? ? ? else
> + ? ? ? ? ? bytes = size_binop (MINUS_EXPR, var_size, bytes);
> + ? ? ? }
> + ? ? ?if (var != pt_var
> + ? ? ? ? && pt_var_size
> + ? ? ? ? && TREE_CODE (pt_var) == INDIRECT_REF
> + ? ? ? ? && bytes != error_mark_node)
> + ? ? ? {
> + ? ? ? ? tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
> + ? ? ? ? if (bytes2 != error_mark_node)
> ? ? ? ? ? ?{
> - ? ? ? ? ? ? if (TREE_CODE (bytes) == INTEGER_CST
> - ? ? ? ? ? ? ? ? && tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes))
> - ? ? ? ? ? ? ? bytes = size_zero_node;
> + ? ? ? ? ? ? if (TREE_CODE (bytes2) == INTEGER_CST
> + ? ? ? ? ? ? ? ? && tree_int_cst_lt (pt_var_size, bytes2))
> + ? ? ? ? ? ? ? bytes2 = size_zero_node;
> ? ? ? ? ? ? ?else
> - ? ? ? ? ? ? ? bytes = size_binop (MINUS_EXPR,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes);
> + ? ? ? ? ? ? ? bytes2 = size_binop (MINUS_EXPR, var_size, bytes2);
> + ? ? ? ? ? ? bytes = size_binop (MIN_EXPR, bytes, bytes2);
> ? ? ? ? ? ?}
> ? ? ? ?}
> - ? ? ?else
> - ? ? ? bytes = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
> -
> - ? ? ?if (host_integerp (bytes, 1))
> - ? ? ? return tree_low_cst (bytes, 1);
> ? ? }
> + ?else if (!pt_var_size)
> + ? ?return unknown[object_size_type];
> + ?else
> + ? ?bytes = pt_var_size;
> +
> + ?if (host_integerp (bytes, 1))
> + ? ?return tree_low_cst (bytes, 1);
>
> ? return unknown[object_size_type];
> ?}
> @@ -332,11 +446,11 @@ compute_builtin_object_size (tree ptr, i
> ? ? init_offset_limit ();
>
> ? if (TREE_CODE (ptr) == ADDR_EXPR)
> - ? ?return addr_object_size (ptr, object_size_type);
> + ? ?return addr_object_size (NULL, ptr, object_size_type);
>
> ? if (TREE_CODE (ptr) == SSA_NAME
> - ? ? ? ? ?&& POINTER_TYPE_P (TREE_TYPE (ptr))
> - ? ? ? ? ?&& object_sizes[object_size_type] != NULL)
> + ? ? ?&& POINTER_TYPE_P (TREE_TYPE (ptr))
> + ? ? ?&& object_sizes[object_size_type] != NULL)
> ? ? {
> ? ? ? if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
> ? ? ? ?{
> @@ -477,7 +591,7 @@ expr_object_size (struct object_size_inf
> ? ? ? ? ? ? ?|| !POINTER_TYPE_P (TREE_TYPE (value)));
>
> ? if (TREE_CODE (value) == ADDR_EXPR)
> - ? ?bytes = addr_object_size (value, object_size_type);
> + ? ?bytes = addr_object_size (osi, value, object_size_type);
> ? else
> ? ? bytes = unknown[object_size_type];
>
> @@ -633,7 +747,7 @@ plus_stmt_object_size (struct object_siz
> ? ? ? ? ?unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
>
> ? ? ? ? ? /* op0 will be ADDR_EXPR here. ?*/
> - ? ? ? ? bytes = compute_builtin_object_size (op0, object_size_type);
> + ? ? ? ? bytes = addr_object_size (osi, op0, object_size_type);
> ? ? ? ? ?if (bytes == unknown[object_size_type])
> ? ? ? ? ? ?;
> ? ? ? ? ?else if (off > offset_limit)
> --- gcc/testsuite/gcc.dg/builtin-object-size-2.c.jj ? ? 2009-06-08 11:53:40.000000000 +0200
> +++ gcc/testsuite/gcc.dg/builtin-object-size-2.c ? ? ? ?2009-06-08 14:10:08.000000000 +0200
> @@ -130,15 +130,15 @@ test1 (void *q, int x)
> ? ? abort ();
> ? if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[0].a, 1) != (size_t) -1)
> + ?if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[10].a[0], 1) != (size_t) -1)
> + ?if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[5].a[4], 1) != (size_t) -1)
> + ?if (__builtin_object_size (&vara[5].a[4], 1) != sizeof (vara[0].a) - 4)
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[5].b, 1) != (size_t) -1)
> + ?if (__builtin_object_size (&vara[5].b, 1) != sizeof (vara[0].b))
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[7].c[7], 1) != (size_t) -1)
> + ?if (__builtin_object_size (&vara[7].c[7], 1) != sizeof (vara[0].c) - 7)
> ? ? abort ();
> ? if (__builtin_object_size (zerol, 1) != 0)
> ? ? abort ();
> --- gcc/testsuite/gcc.dg/builtin-object-size-4.c.jj ? ? 2009-06-08 11:53:40.000000000 +0200
> +++ gcc/testsuite/gcc.dg/builtin-object-size-4.c ? ? ? ?2009-06-08 14:10:19.000000000 +0200
> @@ -130,15 +130,15 @@ test1 (void *q, int x)
> ? ? abort ();
> ? if (__builtin_object_size (&vara[5], 3) != 0)
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[0].a, 3) != 0)
> + ?if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[10].a[0], 3) != 0)
> + ?if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[5].a[4], 3) != 0)
> + ?if (__builtin_object_size (&vara[5].a[4], 3) != sizeof (vara[0].a) - 4)
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[5].b, 3) != 0)
> + ?if (__builtin_object_size (&vara[5].b, 3) != sizeof (vara[0].b))
> ? ? abort ();
> - ?if (__builtin_object_size (&vara[7].c[7], 3) != 0)
> + ?if (__builtin_object_size (&vara[7].c[7], 3) != sizeof (vara[0].c) - 7)
> ? ? abort ();
> ? if (__builtin_object_size (zerol, 3) != 0)
> ? ? abort ();
> --- gcc/testsuite/gcc.dg/builtin-object-size-6.c.jj ? ? 2009-06-08 12:15:20.000000000 +0200
> +++ gcc/testsuite/gcc.dg/builtin-object-size-6.c ? ? ? ?2009-06-08 14:09:27.000000000 +0200
> @@ -0,0 +1,435 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +typedef __SIZE_TYPE__ size_t;
> +extern void abort (void);
> +extern void exit (int);
> +extern void *malloc (size_t);
> +extern void free (void *);
> +
> +struct A
> +{
> + ?char a[10];
> + ?int b;
> + ?char c[10];
> +};
> +
> +void
> +__attribute__ ((noinline))
> +test1 (struct A *p)
> +{
> + ?char *c;
> + ?if (__builtin_object_size (&p->a, 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 0) != (size_t) -1)
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 0) != (size_t) -1)
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 0) != (size_t) -1)
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 0) != (size_t) -1)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 0) != (size_t) -1)
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 1) != (size_t) -1)
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 1) != sizeof (p->b))
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 1) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 2) != 0)
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 2) != 0)
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 2) != 0)
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 2) != 0)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 2) != 0)
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 3) != 0)
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 3) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 3) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 3) != sizeof (p->b))
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 3) != 0)
> + ? ?abort ();
> +}
> +
> +void
> +__attribute__ ((noinline))
> +test2 (void)
> +{
> + ?char *c;
> + ?size_t s = 2 * sizeof (struct A);
> + ?struct A *p = malloc (2 * sizeof (struct A));
> + ?if (__builtin_object_size (&p->a, 0) != s)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 0) != s)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 0) != s - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 0) != s)
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 0) != s)
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 0) != s - 3)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, b))
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 1) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 1) != sizeof (p->b))
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 1) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 2) != s)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 2) != s)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 2) != s - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 2) != s - __builtin_offsetof (struct A, b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 2) != s)
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 2) != s)
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 2) != s - 3)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, b))
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 3) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?c = p->a;
> + ?if (__builtin_object_size (c, 3) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[0];
> + ?if (__builtin_object_size (c, 3) != sizeof (p->a))
> + ? ?abort ();
> + ?c = &p->a[3];
> + ?if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?c = (char *) &p->b;
> + ?if (__builtin_object_size (c, 3) != sizeof (p->b))
> + ? ?abort ();
> + ?c = (char *) &p->c;
> + ?if (__builtin_object_size (c, 3) != s - __builtin_offsetof (struct A, c))
> + ? ?abort ();
> + ?free (p);
> +}
> +
> +void
> +__attribute__ ((noinline))
> +test3 (void)
> +{
> + ?char *c;
> + ?size_t s;
> + ?struct A *p = malloc (4);
> + ?if (__builtin_object_size (&p->a, 0) != 4)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 0) != 4)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 0) != 1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 0) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 0) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 1) != 4)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 1) != 4)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 1) != 1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 1) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 1) != 0)
> + ? ?abort ();
> + ?free (p);
> + ?s = __builtin_offsetof (struct A, c) + 4;
> + ?p = malloc (s);
> + ?if (__builtin_object_size (&p->a, 0) != s)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 0) != s)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 0) != s - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 0) != 4)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
> + ? ?abort ();
> + ?if (__builtin_object_size (&p->c, 1) != 4)
> + ? ?abort ();
> + ?free (p);
> +}
> +
> +struct B
> +{
> + ?struct A a[4];
> +};
> +
> +void
> +__attribute__ ((noinline))
> +test4 (struct B *q, int i)
> +{
> + ?if (__builtin_object_size (&q->a[2].a[2], 1) != sizeof (q->a[0].a) - 2)
> + ? ?abort ();
> + ?if (__builtin_object_size (&q->a[2].c[2], 1) != sizeof (q->a[0].c) - 2)
> + ? ?abort ();
> + ?if (__builtin_object_size (&q->a[3].a[2], 1) != sizeof (q->a[0].a) - 2)
> + ? ?abort ();
> + ?if (__builtin_object_size (&q->a[3].c[2], 1) != sizeof (q->a[0].c) - 2)
> + ? ?abort ();
> + ?if (__builtin_object_size (&q->a[i].a[2], 1) != sizeof (q->a[0].a) - 2)
> + ? ?abort ();
> + ?if (__builtin_object_size (&q->a[i].c[2], 1) != sizeof (q->a[0].c) - 2)
> + ? ?abort ();
> +}
> +
> +struct C
> +{
> + ?char a[10];
> + ?char b;
> +};
> +
> +void
> +__attribute__ ((noinline))
> +test5 (struct C *c)
> +{
> + ?if (__builtin_object_size (&c->b, 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&c->b, 1) != 1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&c->b, 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&c->b, 3) != 1)
> + ? ?abort ();
> +}
> +
> +struct D
> +{
> + ?int i;
> + ?struct D1
> + ?{
> + ? ?char b;
> + ? ?char a[10];
> + ?} j;
> +};
> +
> +void
> +__attribute__ ((noinline))
> +test6 (struct D *d)
> +{
> + ?if (__builtin_object_size (&d->j.a[3], 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&d->j.a[3], 1) != sizeof (d->j.a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&d->j.a[3], 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&d->j.a[3], 3) != sizeof (d->j.a) - 3)
> + ? ?abort ();
> +}
> +
> +struct E
> +{
> + ?int i;
> + ?struct E1
> + ?{
> + ? ?char b;
> + ? ?char a[10];
> + ?} j[1];
> +};
> +
> +void
> +__attribute__ ((noinline))
> +test7 (struct E *e)
> +{
> + ?if (__builtin_object_size (&e->j[0].a[3], 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&e->j[0].a[3], 1) != sizeof (e->j[0].a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&e->j[0].a[3], 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&e->j[0].a[3], 3) != sizeof (e->j[0].a) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size ((char *) &e->j[0], 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size ((char *) &e->j[0], 1) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size ((char *) &e->j[0], 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size ((char *) &e->j[0], 3) != 0)
> + ? ?abort ();
> +}
> +
> +union F
> +{
> + ?char a[1];
> + ?struct F1
> + ?{
> + ? ?char b;
> + ? ?char c[10];
> + ?} d;
> +};
> +
> +void
> +__attribute__ ((noinline))
> +test8 (union F *f)
> +{
> + ?if (__builtin_object_size (&f->d.c[3], 0) != (size_t) -1)
> + ? ?abort ();
> + ?if (__builtin_object_size (&f->d.c[3], 1) != sizeof (f->d.c) - 3)
> + ? ?abort ();
> + ?if (__builtin_object_size (&f->d.c[3], 2) != 0)
> + ? ?abort ();
> + ?if (__builtin_object_size (&f->d.c[3], 3) != sizeof (f->d.c) - 3)
> + ? ?abort ();
> +}
> +
> +int
> +main (void)
> +{
> + ?struct A a, *p = &a;
> + ?int i = 1;
> + ?__asm ("" : "+r" (p));
> + ?test1 (p);
> + ?test2 ();
> + ?test3 ();
> + ?struct B b, *q = &b;
> + ?__asm ("" : "+r" (q), "+r" (i));
> + ?test4 (q, i);
> + ?struct C c, *cp = &c;
> + ?__asm ("" : "+r" (cp));
> + ?test5 (cp);
> + ?struct D d, *dp = &d;
> + ?__asm ("" : "+r" (dp));
> + ?test6 (dp);
> + ?struct E e, *ep = &e;
> + ?__asm ("" : "+r" (ep));
> + ?test7 (ep);
> + ?union F f, *fp = &f;
> + ?__asm ("" : "+r" (fp));
> + ?test8 (fp);
> + ?exit (0);
> +}
>
>
> ? ? ? ?Jakub
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]