From da19297d259fcb78814efb18314a7948a1cc0d15 Mon Sep 17 00:00:00 2001 From: Olivier Hainque Date: Wed, 14 May 2008 15:05:16 +0000 Subject: [PATCH] expr.c (expand_expr_real_1): Force op0 to memory if the component is to be referenced in BLKmode according... * expr.c (expand_expr_real_1) : Force op0 to memory if the component is to be referenced in BLKmode according to get_inner_reference. testsuite/ * gnat.dg/blkextract_from_reg.adb: New test. From-SVN: r135296 --- gcc/ChangeLog | 6 +++ gcc/expr.c | 11 +++-- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gnat.dg/blkextract_from_reg.adb | 49 +++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/blkextract_from_reg.adb diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9b6a5d2641e..b7c1870085d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-05-14 Olivier Hainque + + * expr.c (expand_expr_real_1) : Force op0 to + memory if the component is to be referenced in BLKmode according + to get_inner_reference. + 2008-05-14 Adam Nemet * calls.c (emit_library_call_value_1): Restore code clearing diff --git a/gcc/expr.c b/gcc/expr.c index d2fc6d0cc5f..0bf82382400 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0ff79cc73b0..7f8b32d9d4c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-05-14 Olivier Hainque + + * gnat.dg/blkextract_from_reg.adb: New test. + 2008-05-14 Francois-Xavier Coudert 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 index 00000000000..204d71964c7 --- /dev/null +++ b/gcc/testsuite/gnat.dg/blkextract_from_reg.adb @@ -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; -- 2.30.2