re PR c/27184 (Wrong code with pointers to arrays and types and strict aliasing)

2006-08-13  Alexandre Oliva  <aoliva@redhat.com>
            Andrew Pinski  <pinskia@physics.uc.edu>

        PR c/27184
        * tree.c (build_array_type): Unify array types with
        unspecified index_type.
        * c-decl.c (grokdeclarator): Make sure we do not modify a
        unified incomplete array type.
        * c-typeck.c (store_init_value): Create distinct type before
        filling in the index type in an initializer from a compound
        literal.

        * c-decl.c (grokdeclarator): Remove code where we copy the
        array type over.

2006-08-13  Alexandre Oliva  <aoliva@redhat.com>

        PR c/27184
        * gcc.dg/torture/pr27184.c: New test


Co-Authored-By: Andrew Pinski <pinskia@physics.uc.edu>

From-SVN: r116116
This commit is contained in:
Alexandre Oliva 2006-08-13 20:16:46 +00:00 committed by Andrew Pinski
parent 0bff60e5b7
commit 8d9f82d593
6 changed files with 78 additions and 20 deletions

View File

@ -1,3 +1,18 @@
2006-08-13 Alexandre Oliva <aoliva@redhat.com>
Andrew Pinski <pinskia@physics.uc.edu>
PR c/27184
* tree.c (build_array_type): Unify array types with
unspecified index_type.
* c-decl.c (grokdeclarator): Make sure we do not modify a
unified incomplete array type.
* c-typeck.c (store_init_value): Create distinct type before
filling in the index type in an initializer from a compound
literal.
* c-decl.c (grokdeclarator): Remove code where we copy the
array type over.
2006-08-13 Andrew Pinski <pinskia@physics.uc.edu>
* tree-pass.h (TODO_update_ssa): Fix which bit is used to take

View File

@ -4309,6 +4309,18 @@ grokdeclarator (const struct c_declarator *declarator,
size_varies = 1;
}
}
else if (decl_context == TYPENAME)
{
if (array_parm_vla_unspec_p)
{
/* The error is printed elsewhere. We use this to
avoid messing up with incomplete array types of
the same type, that would otherwise be modified
below. */
itype = build_range_type (sizetype, size_zero_node,
NULL_TREE);
}
}
/* Complain about arrays of incomplete types. */
if (!COMPLETE_TYPE_P (type))
@ -4317,12 +4329,23 @@ grokdeclarator (const struct c_declarator *declarator,
type = error_mark_node;
}
else
/* When itype is NULL, a shared incomplete array type is
returned for all array of a given type. Elsewhere we
make sure we don't complete that type before copying
it, but here we want to make sure we don't ever
modify the shared type, so we gcc_assert (itype)
below. */
type = build_array_type (type, itype);
if (type != error_mark_node)
{
if (size_varies)
{
/* It is ok to modify type here even if itype is
NULL: if size_varies, we're in a
multi-dimentional array and the inner type has
variable size, so the enclosing shared array type
must too. */
if (size && TREE_CODE (size) == INTEGER_CST)
type
= build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
@ -4334,11 +4357,13 @@ grokdeclarator (const struct c_declarator *declarator,
zero. */
if (size && integer_zerop (size))
{
gcc_assert (itype);
TYPE_SIZE (type) = bitsize_zero_node;
TYPE_SIZE_UNIT (type) = size_zero_node;
}
if (array_parm_vla_unspec_p)
{
gcc_assert (itype);
/* The type is complete. C99 6.7.5.2p4 */
TYPE_SIZE (type) = bitsize_zero_node;
TYPE_SIZE_UNIT (type) = size_zero_node;
@ -4497,21 +4522,6 @@ grokdeclarator (const struct c_declarator *declarator,
return decl;
}
/* Detect the case of an array type of unspecified size
which came, as such, direct from a typedef name.
We must copy the type, so that each identifier gets
a distinct type, so that each identifier's size can be
controlled separately by its own initializer. */
if (type != 0 && typedef_type != 0
&& TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
{
type = build_array_type (TREE_TYPE (type), 0);
if (size_varies)
C_TYPE_VARIABLE_SIZE (type) = 1;
}
/* If this is a type name (such as, in a cast or sizeof),
compute the type and return it now. */

View File

@ -4326,16 +4326,18 @@ store_init_value (tree decl, tree init)
if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
{
tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
tree cldecl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
if (TYPE_DOMAIN (TREE_TYPE (decl)))
if (TYPE_DOMAIN (TREE_TYPE (cldecl)))
{
/* For int foo[] = (int [3]){1}; we need to set array size
now since later on array initializer will be just the
brace enclosed list of the compound literal. */
TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (decl));
type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
TREE_TYPE (decl) = type;
TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl));
layout_type (type);
layout_decl (decl, 0);
layout_decl (cldecl, 0);
}
}
}

View File

@ -1,3 +1,8 @@
2006-08-13 Alexandre Oliva <aoliva@redhat.com>
PR c/27184
* gcc.dg/torture/pr27184.c: New test.
2006-08-12 Jakub Jelinek <jakub@redhat.com>
* gcc.target/i386/pr27827.c: Only compile on ilp32 target.

View File

@ -0,0 +1,22 @@
/* Copyright 2006 Free Software Foundation */
/* Make sure a and a1 alias each other.
Incomplete array types used to not be unified, which broke aliasing. */
/* { dg-do run } */
typedef long atype[];
typedef long atype1[];
int NumSift (atype *a, atype1 *a1)
{
(*a)[0] = 0;
(*a1)[0] = 1;
return (*a)[0];
}
int main(void)
{
long a[2];
if (!NumSift(&a, &a))
__builtin_abort ();
return 0;
}

View File

@ -5158,7 +5158,11 @@ build_array_type (tree elt_type, tree index_type)
if (index_type == 0)
{
layout_type (t);
tree save = t;
hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
t = type_hash_canon (hashcode, t);
if (save == t)
layout_type (t);
return t;
}