* expr.c (expand_expr_real_1) <normal_inner_ref>: Force op0 to
authorhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 May 2008 15:05:16 +0000 (15:05 +0000)
committerhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 May 2008 15:05:16 +0000 (15:05 +0000)
        memory if the component is to be referenced in BLKmode according
        to get_inner_reference.

        testsuite/
        * gnat.dg/blkextract_from_reg.adb: New test.

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

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/blkextract_from_reg.adb [new file with mode: 0644]

index 9b6a5d2..b7c1870 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-14  Olivier Hainque  <hainque@adacore.com>
+
+       * expr.c (expand_expr_real_1) <normal_inner_ref>: Force op0 to
+       memory if the component is to be referenced in BLKmode according
+       to get_inner_reference.
+
 2008-05-14  Adam Nemet  <anemet@caviumnetworks.com>
 
        * calls.c (emit_library_call_value_1): Restore code clearing
index d2fc6d0..0bf8238 100644 (file)
@@ -7739,13 +7739,15 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        /* If this is a constant, put it into a register if it is a legitimate
           constant, OFFSET is 0, and we won't try to extract outside the
           register (in case we were passed a partially uninitialized object
-          or a view_conversion to a larger size).  Force the constant to
-          memory otherwise.  */
+          or a view_conversion to a larger size) or a BLKmode piece of it
+          (e.g. if it is unchecked-converted to a record type in Ada).  Force
+          the constant to memory otherwise.  */
        if (CONSTANT_P (op0))
          {
            enum machine_mode mode = TYPE_MODE (TREE_TYPE (tem));
            if (mode != BLKmode && LEGITIMATE_CONSTANT_P (op0)
                && offset == 0
+               && mode1 != BLKmode
                && bitpos + bitsize <= GET_MODE_BITSIZE (mode))
              op0 = force_reg (mode, op0);
            else
@@ -7759,8 +7761,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
           for an ARRAY_RANGE_REF whose type is BLKmode.  */
        else if (!MEM_P (op0)
                 && (offset != 0
-                    || (bitpos + bitsize > GET_MODE_BITSIZE (GET_MODE (op0)))
-                    || (code == ARRAY_RANGE_REF && mode == BLKmode)))
+                    || mode1 == BLKmode
+                    || (bitpos + bitsize
+                        > GET_MODE_BITSIZE (GET_MODE (op0)))))
          {
            tree nt = build_qualified_type (TREE_TYPE (tem),
                                            (TYPE_QUALS (TREE_TYPE (tem))
index 0ff79cc..7f8b32d 100644 (file)
@@ -1,3 +1,7 @@
+2008-05-14  Olivier Hainque  <hainque@adacore.com>
+
+       * gnat.dg/blkextract_from_reg.adb: New test.
+
 2008-05-14  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/36215
diff --git a/gcc/testsuite/gnat.dg/blkextract_from_reg.adb b/gcc/testsuite/gnat.dg/blkextract_from_reg.adb
new file mode 100644 (file)
index 0000000..204d719
--- /dev/null
@@ -0,0 +1,49 @@
+--  { dg-do run }
+
+with System, Ada.Unchecked_Conversion; use System;
+
+procedure BLKextract_From_Reg is
+
+   type Byte is range 0 .. +255;
+   for  Byte'size use 8;
+
+   type RGB is array (1 .. 3) of Byte;
+   for RGB'Size use 24;
+
+   type RAW_Packet is range 0 .. 2 ** 32 - 1;
+   for  RAW_Packet'Size use 32;
+
+   type Composite_Packet is record
+      Values : RGB;
+      Pad    : Byte;
+   end record;
+   for Composite_Packet use record
+      Values at 0 range 0 .. 23;
+      Pad    at 3 range 0 .. 7;
+   end record;
+   for Composite_Packet'Size use 32;
+
+   function To_Composite_Packet is
+      new Ada.Unchecked_Conversion (RAW_Packet, Composite_Packet);
+
+   function Blob return RGB is
+      RAW_Blob : RAW_Packet := 16#01020304#;
+   begin
+      return To_Composite_Packet (RAW_Blob).Values;
+   end;
+
+   Blob_Color : RGB := Blob;
+   Expected_Color : RGB;
+begin
+   if System.Default_Bit_Order = High_Order_First then
+      Expected_Color := (1 => 1, 2 => 2, 3 => 3);
+   else
+      Expected_Color := (1 => 4, 2 => 3, 3 => 2);
+   end if;
+   
+   for I in Blob_Color'Range loop
+      if Blob_Color (I) /= Expected_Color (I) then
+        raise Program_Error;
+      end if;
+   end loop;
+end;