c-common.c (c_common_get_alias_set): Correctly handle characters.
authorRichard Henderson <rth@redhat.com>
Thu, 20 Jun 2002 07:30:04 +0000 (00:30 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 20 Jun 2002 07:30:04 +0000 (00:30 -0700)
        * c-common.c (c_common_get_alias_set): Correctly handle characters.
        Rearrange order of expressions; don't handle vectors here.
        * alias.c (get_alias_set): Let vectors match their components.

From-SVN: r54821

gcc/ChangeLog
gcc/alias.c
gcc/c-common.c
gcc/testsuite/gcc.c-torture/execute/20020619-1.c [new file with mode: 0644]

index 2a26702298deab2e067cc3503a786f70eaae1dde..710e2cd3d473b13b27cb19823edde6ca9a95a120 100644 (file)
@@ -1,3 +1,9 @@
+2002-05-20  Richard Henderson  <rth@redhat.com>
+
+       * c-common.c (c_common_get_alias_set): Correctly handle characters.
+       Rearrange order of expressions; don't handle vectors here.
+       * alias.c (get_alias_set): Let vectors match their components.
+
 2002-06-19  Chris Demetriou  <cgd@broadcom.com>
 
         * config/mips/mips.c (mips_emit_prefetch): Use hints which
index d892926b453bed06aa67d3b3ca7674f28d78e1b6..2e6a2b084e154f51998ce7afa46d442f3924e93f 100644 (file)
@@ -575,6 +575,14 @@ get_alias_set (t)
      and references to functions, but that's different.)  */
   else if (TREE_CODE (t) == FUNCTION_TYPE)
     set = 0;
+
+  /* Unless the language specifies otherwise, let vector types alias
+     their components.  This avoids some nasty type punning issues in
+     normal usage.  And indeed lets vectors be treated more like an
+     array slice.  */
+  else if (TREE_CODE (t) == VECTOR_TYPE)
+    set = get_alias_set (TREE_TYPE (t));
+
   else
     /* Otherwise make a new alias set for this type.  */
     set = new_alias_set ();
index b477fe78f165a3553918e95841bfd752d305b58c..c71f75270066cc78194a5e22bf13f2fc8915cfd6 100644 (file)
@@ -2527,10 +2527,6 @@ c_common_get_alias_set (t)
 {
   tree u;
   
-  /* We know nothing about vector types */
-  if (TREE_CODE (t) == VECTOR_TYPE)
-    return 0;          
-  
   /* Permit type-punning when accessing a union, provided the access
      is directly through the union.  For example, this code does not
      permit taking the address of a union member and then storing
@@ -2544,21 +2540,21 @@ c_common_get_alias_set (t)
        && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
       return 0;
 
-  /* If this is a char *, the ANSI C standard says it can alias
-     anything.  Note that all references need do this.  */
-  if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r'
-      && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
-      && TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node))
+  /* That's all the expressions we handle specially.  */
+  if (! TYPE_P (t))
+    return -1;
+
+  /* The C standard guarantess that any object may be accessed via an
+     lvalue that has character type.  */
+  if (t == char_type_node
+      || t == signed_char_type_node
+      || t == unsigned_char_type_node)
     return 0;
 
   /* If it has the may_alias attribute, it can alias anything.  */
-  if (TYPE_P (t) && lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
+  if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
     return 0;
 
-  /* That's all the expressions we handle specially.  */
-  if (! TYPE_P (t))
-    return -1;
-
   /* The C standard specifically allows aliasing between signed and
      unsigned variants of the same type.  We treat the signed
      variant as canonical.  */
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020619-1.c b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c
new file mode 100644 (file)
index 0000000..5ed4d00
--- /dev/null
@@ -0,0 +1,32 @@
+static int ref(void)
+{
+  union {
+    char c[5];
+    int i;
+  } u;
+
+  __builtin_memset (&u, 0, sizeof(u));
+  u.c[0] = 1;
+  u.c[1] = 2;
+  u.c[2] = 3;
+  u.c[3] = 4;
+
+  return u.i;
+}
+
+#define MAX(a,b)  (a < b ? b : a)
+
+static int test(void)
+{
+  char c[MAX(5, sizeof(int))] __attribute__((aligned)) = { 1, 2, 3, 4 };
+  return *(int *)c;
+}
+
+int main()
+{
+  int a = test();
+  int b = ref();
+  if (a != b)
+    abort ();
+  return 0;
+}