re PR c/27184 (Wrong code with pointers to arrays and types and strict aliasing)
authorAlexandre Oliva <aoliva@redhat.com>
Sun, 13 Aug 2006 20:16:46 +0000 (20:16 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Sun, 13 Aug 2006 20:16:46 +0000 (13:16 -0700)
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

gcc/ChangeLog
gcc/c-decl.c
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr27184.c [new file with mode: 0644]
gcc/tree.c

index 877756776bf57a317afa962d86b31a9b028b176b..37fbac8519ccc811a23de7d5b4255c7fc6d3abc9 100644 (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
index 9a0e747c71384a6c58dfa85040bfa37460d9cef0..21b10a60b43376be76ae1824127933d86ba46ec8 100644 (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.  */
 
index ff27c973094005f09d0f5eed1ec4896114257e42..506b60fb0fec9be9fed7de4fbed8e88b171faadf 100644 (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);
            }
        }
     }
index f70afc750db02d765fba41282849f73d66b8e619..de4f9e6a789dc7442ad9d22415acc24e6847a2c4 100644 (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.
diff --git a/gcc/testsuite/gcc.dg/torture/pr27184.c b/gcc/testsuite/gcc.dg/torture/pr27184.c
new file mode 100644 (file)
index 0000000..cfb6ed2
--- /dev/null
@@ -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;
+}
index efccfb11d9a1e28d53056dfc85f1844694403852..f4e53ef592ffbed8db16d4ada2771facfe3b9274 100644 (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;
     }