diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-19 14:45:16 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-19 14:45:16 +0000 |
commit | fc0bb78b0c166626a9be6988707825660807e7ef (patch) | |
tree | ac0e212d9e729fb65c18549463678f0d9037031a | |
parent | b9b03799fa559d095373088ebbda65a51bd8fbc2 (diff) | |
download | ppe42-gcc-fc0bb78b0c166626a9be6988707825660807e7ef.tar.gz ppe42-gcc-fc0bb78b0c166626a9be6988707825660807e7ef.zip |
* expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: For a bit-field
destination type, extract only the valid bits if the source type is not
integral and has a different mode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207902 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt31.adb | 43 |
4 files changed, 62 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a71885409b3..eca2f7a780b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-02-19 Eric Botcazou <ebotcazou@adacore.com> + + * expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: For a bit-field + destination type, extract only the valid bits if the source type is not + integral and has a different mode. + 2014-02-19 Richard Biener <rguenther@suse.de> PR ipa/60243 diff --git a/gcc/expr.c b/gcc/expr.c index 29ce694704c..be62c539e25 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10436,6 +10436,11 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))) op0 = convert_modes (mode, GET_MODE (op0), op0, TYPE_UNSIGNED (TREE_TYPE (treeop0))); + /* If the output type is a bit-field type, do an extraction. */ + else if (reduce_bit_field) + return extract_bit_field (op0, TYPE_PRECISION (type), 0, + TYPE_UNSIGNED (type), NULL_RTX, + mode, mode); /* As a last resort, spill op0 to memory, and reload it in a different mode. */ else if (!MEM_P (op0)) @@ -10458,10 +10463,10 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, op0 = target; } - /* At this point, OP0 is in the correct mode. If the output type is - such that the operand is known to be aligned, indicate that it is. - Otherwise, we need only be concerned about alignment for non-BLKmode - results. */ + /* If OP0 is (now) a MEM, we need to deal with alignment issues. If the + output type is such that the operand is known to be aligned, indicate + that it is. Otherwise, we need only be concerned about alignment for + non-BLKmode results. */ if (MEM_P (op0)) { enum insn_code icode; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a7aa8c2f9d1..c34f640710b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-02-19 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/opt31.adb: New test. + 2014-02-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * gcc.dg/torture/pr60092.c: xfail execution on *-*-solaris2.11* at -O0. diff --git a/gcc/testsuite/gnat.dg/opt31.adb b/gcc/testsuite/gnat.dg/opt31.adb new file mode 100644 index 00000000000..51aa3556cec --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt31.adb @@ -0,0 +1,43 @@ +-- { dg-do run } +-- { dg-options "-O" } + +with Interfaces; use Interfaces; +with Unchecked_Conversion; + +procedure Opt31 is + + type Unsigned_24 is new Unsigned_32 range 0 .. 2**24 - 1; + subtype Time_T is Unsigned_24 range 0 .. 24 * 60 * 60 * 128 - 1; + + type Messages_T is array (Positive range <>) of Unsigned_8; + subtype T_3Bytes is Messages_T (1 .. 3); + + type Rec1 is record + F : Time_T; + end record; + for Rec1 use record + F at 0 range 0 .. 23; + end record; + for Rec1'Size use 24; + + type Rec2 is record + I1,I2,I3,I4 : Integer; + R1 : Rec1; + end record; + + function Conv is new Unchecked_Conversion (T_3Bytes, Rec1); + + procedure Decode (M : Messages_T) is + My_Rec2 : Rec2; + begin + My_Rec2.R1 := Conv (M (1 .. 3)); + if not My_Rec2.R1.F'Valid then + raise Program_Error; + end if; + end; + + Message : Messages_T (1 .. 4) := (16#18#, 16#0C#, 16#0C#, 16#18#); + +begin + Decode (Message); +end; |