From 056c8faea0671ac8b20504f688e2459386dc18c3 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 11 Jun 2008 15:56:41 +0000 Subject: [PATCH] builtins.c (get_memory_rtx): Accept byte-addressable bitfields. * 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 From-SVN: r136673 --- gcc/ChangeLog | 6 ++++++ gcc/builtins.c | 16 +++++++++----- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/varsize_copy.adb | 24 +++++++++++++++++++++ gcc/testsuite/gnat.dg/varsize_copy.ads | 30 ++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/varsize_copy.adb create mode 100644 gcc/testsuite/gnat.dg/varsize_copy.ads diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a8f88990e0..78ee5bd6456 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-06-11 Eric Botcazou + Olivier Hainque + + * 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 * config/arm/arm.c (arm_init_neon_builtins): Move initialization diff --git a/gcc/builtins.c b/gcc/builtins.c index 8abcc114647..edc5d5f07f3 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 072a5cb948f..08bd74ca624 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-06-11 Eric Botcazou + + * gnat.dg/specs/varsize_copy.ad[sb]: New test. + 2008-06-10 Uros Bizjak * 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 index 00000000000..4fa0ff8622e --- /dev/null +++ b/gcc/testsuite/gnat.dg/varsize_copy.adb @@ -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 index 00000000000..9a088a9ffdf --- /dev/null +++ b/gcc/testsuite/gnat.dg/varsize_copy.ads @@ -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; -- 2.30.2