aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-06-11 15:56:41 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-06-11 15:56:41 +0000
commit056c8faea0671ac8b20504f688e2459386dc18c3 (patch)
tree7f4fdceccc7546f3261363ae2dab1aa312a764f3 /gcc
parent2023be161a9a1ec80e84c8fe231b38a4020b629f (diff)
downloadgcc-056c8faea0671ac8b20504f688e2459386dc18c3.zip
gcc-056c8faea0671ac8b20504f688e2459386dc18c3.tar.gz
gcc-056c8faea0671ac8b20504f688e2459386dc18c3.tar.bz2
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 <hainque@adacore.com> From-SVN: r136673
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/builtins.c16
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/varsize_copy.adb24
-rw-r--r--gcc/testsuite/gnat.dg/varsize_copy.ads30
5 files changed, 75 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8a8f889..78ee5bd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 8abcc11..edc5d5f 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 072a5cb..08bd74c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..4fa0ff8
--- /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 0000000..9a088a9
--- /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;