aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2006-08-13 20:16:46 +0000
committerAndrew Pinski <pinskia@gcc.gnu.org>2006-08-13 13:16:46 -0700
commit8d9f82d59362f88ccf848a76285ae44024981ac0 (patch)
tree872017de3d83c2f55ee00df495e2809bd786b19c
parent0bff60e5b729caa36d6669be4a964b87a9b6081b (diff)
downloadgcc-8d9f82d59362f88ccf848a76285ae44024981ac0.zip
gcc-8d9f82d59362f88ccf848a76285ae44024981ac0.tar.gz
gcc-8d9f82d59362f88ccf848a76285ae44024981ac0.tar.bz2
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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/c-decl.c40
-rw-r--r--gcc/c-typeck.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr27184.c22
-rw-r--r--gcc/tree.c6
6 files changed, 78 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8777567..37fbac8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 9a0e747..21b10a6 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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. */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index ff27c97..506b60f 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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);
}
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f70afc7..de4f9e6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/torture/pr27184.c b/gcc/testsuite/gcc.dg/torture/pr27184.c
new file mode 100644
index 0000000..cfb6ed2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr27184.c
@@ -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;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index efccfb1..f4e53ef 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
}