OSDN Git Service

* alias.c (get_alias_set): Return a previously calculated
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 Aug 2001 11:13:54 +0000 (11:13 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 Aug 2001 11:13:54 +0000 (11:13 +0000)
        alias set for a VAR_DECL.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44683 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/alias.c
gcc/testsuite/g++.dg/opt/alias1.C [new file with mode: 0644]

index 7c66b67..760dd95 100644 (file)
@@ -1,3 +1,8 @@
+2001-08-07  Jason Merrill  <jason_merrill@redhat.com>
+
+       * alias.c (get_alias_set): Return a previously calculated
+       alias set for a VAR_DECL.
+
 2001-08-06  Richard Henderson  <rth@redhat.com>
 
        * varasm.c (assemble_gc_entry): Remove.
index e741718..a529a01 100644 (file)
@@ -527,6 +527,13 @@ get_alias_set (t)
            return 0;
        }
 
+      /* If we've already determined the alias set for this decl, just
+        return it.  This is necessary for C++ anonymous unions, whose
+        component variables don't look like union members (boo!).  */
+      if (TREE_CODE (t) == VAR_DECL
+         && DECL_RTL_SET_P (t) && GET_CODE (DECL_RTL (t)) == MEM)
+       return MEM_ALIAS_SET (DECL_RTL (t));
+
       /* Give the language another chance to do something special.  */
       if (orig_t != t
          && (set = lang_get_alias_set (t)) != -1)
diff --git a/gcc/testsuite/g++.dg/opt/alias1.C b/gcc/testsuite/g++.dg/opt/alias1.C
new file mode 100644 (file)
index 0000000..34aed59
--- /dev/null
@@ -0,0 +1,25 @@
+// Test that type punning using an anonymous union works with strict aliasing.
+// { dg-do run }
+// { dg-options -O2 -fstrict-aliasing }
+
+extern "C" void abort ();
+
+void f (int i)
+{
+  union
+  {
+    int ui;
+    float uf[2];
+  };
+
+  ui = i;
+  if (uf[0] != 42.0)
+    abort ();
+}
+
+int main ()
+{
+  union U { int i; float f[2]; } u;
+  u.f[0] = 42.0;
+  f (u.i);
+}