builtins.c (get_memory_rtx): Accept byte-addressable bitfields.
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 11 Jun 2008 15:56:41 +0000 (15:56 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 11 Jun 2008 15:56:41 +0000 (15:56 +0000)
* builtins.c (get_memory_rtx): Accept byte-addressable bitfields.
Use DECL_SIZE_UNIT to retrieve the size of the field.

Co-Authored-By: Olivier Hainque <hainque@adacore.com>
From-SVN: r136673

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/varsize_copy.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/varsize_copy.ads [new file with mode: 0644]

index 8a8f88990e096e7eca4e6201d2004edff4edde8f..78ee5bd64567d39524627fc1dd183812ece80af6 100644 (file)
@@ -1,3 +1,9 @@
+2008-06-11  Eric Botcazou  <ebotcazou@adacore.com>
+            Olivier Hainque  <hainque@adacore.com>
+
+       * builtins.c (get_memory_rtx): Accept byte-addressable bitfields.
+       Use DECL_SIZE_UNIT to retrieve the size of the field.
+
 2008-06-11  Joseph Myers  <joseph@codesourcery.com>
 
        * config/arm/arm.c (arm_init_neon_builtins): Move initialization
index 8abcc114647fbba1d126bf7aed5ab007c10dfc69..edc5d5f07f3e65152588ebb2c668f80c9ca014f8 100644 (file)
@@ -1114,16 +1114,22 @@ get_memory_rtx (tree exp, tree len)
          while (TREE_CODE (inner) == COMPONENT_REF)
            {
              tree field = TREE_OPERAND (inner, 1);
-             gcc_assert (! DECL_BIT_FIELD (field));
              gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
              gcc_assert (field == TREE_OPERAND (mem_expr, 1));
 
+             /* Bitfields are generally not byte-addressable.  */
+             gcc_assert (!DECL_BIT_FIELD (field)
+                         || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
+                              % BITS_PER_UNIT) == 0
+                             && host_integerp (DECL_SIZE (field), 0)
+                             && (TREE_INT_CST_LOW (DECL_SIZE (field))
+                                 % BITS_PER_UNIT) == 0));
+
              if (length >= 0
-                 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
-                 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
+                 && host_integerp (DECL_SIZE_UNIT (field), 0))
                {
                  HOST_WIDE_INT size
-                   = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
+                   = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
                  /* If we can prove the memory starting at XEXP (mem, 0)
                     and ending at XEXP (mem, 0) + LENGTH will fit into
                     this field, we can keep that COMPONENT_REF in MEM_EXPR.  */
@@ -1135,7 +1141,7 @@ get_memory_rtx (tree exp, tree len)
 
              if (offset >= 0
                  && host_integerp (DECL_FIELD_OFFSET (field), 0))
-               offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
+               offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
                          + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
                            / BITS_PER_UNIT;
              else
index 072a5cb948f955451d287a4fa4a2cd485903e0f3..08bd74ca62411c7c14008e4e87b9c41ba3b3937a 100644 (file)
@@ -1,3 +1,7 @@
+2008-06-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/specs/varsize_copy.ad[sb]: New test.
+
 2008-06-10  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.target/i386/bt-mask-1.c: New test.
diff --git a/gcc/testsuite/gnat.dg/varsize_copy.adb b/gcc/testsuite/gnat.dg/varsize_copy.adb
new file mode 100644 (file)
index 0000000..4fa0ff8
--- /dev/null
@@ -0,0 +1,24 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatws" }
+
+package body Varsize_Copy is
+
+   type Key_Mapping_Type is record
+      Page : Page_Type;
+      B    : Boolean;
+   end record;
+
+   type Key_Mapping_Array is array (Key_Type) of Key_Mapping_Type;
+
+   type Set is record
+      Key_Mappings : Key_Mapping_Array;
+   end record;
+
+   S : Set;
+
+   function F (Key : Key_Type) return Page_Type is
+   begin
+      return S.Key_Mappings (Key).Page;
+   end;
+
+end Varsize_Copy;
diff --git a/gcc/testsuite/gnat.dg/varsize_copy.ads b/gcc/testsuite/gnat.dg/varsize_copy.ads
new file mode 100644 (file)
index 0000000..9a088a9
--- /dev/null
@@ -0,0 +1,30 @@
+package Varsize_Copy is
+
+   type Key_Type is
+      (Nul, Cntrl, Stx, Etx, Eot, Enq, Ack, Spad, Clr, Dc_1, Dc_2, Dc_3, Dc_4);
+
+   for Key_Type use
+      (Nul   => 0,
+       Cntrl => 1,
+       Stx   => 2,
+       Etx   => 3,
+       Eot   => 4,
+       Enq   => 5,
+       Ack   => 6,
+       Spad  => 7,
+       Clr   => 8,
+       Dc_1  => 17,
+       Dc_2  => 18,
+       Dc_3  => 19,
+       Dc_4  => 20);
+
+   type Page_Type(D : Boolean := False) is record
+      case D is
+         when True => I : Integer;
+         when False => null;
+      end case;
+   end record;
+
+   function F (Key : Key_Type) return Page_Type;
+
+end Varsize_Copy;