aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2004-09-26 14:58:34 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2004-09-26 14:58:34 +0000
commit897f610ba4492354c4bab4d61f476dc8d27c9124 (patch)
treeaa76381885409572a4b6e89bce34c27e9ce000c8 /gcc
parent5c8c573a86eddc5949d59c602704775d1671a8fb (diff)
downloadgcc-897f610ba4492354c4bab4d61f476dc8d27c9124.zip
gcc-897f610ba4492354c4bab4d61f476dc8d27c9124.tar.gz
gcc-897f610ba4492354c4bab4d61f476dc8d27c9124.tar.bz2
re PR middle-end/17112 (Copying of packed bitfields is wrong)
PR middle-end/17112 * stor-layout.c (compute_record_mode): For records with a single field, only use the field's mode if its size matches what we'd have choosen for the record ourselves. This forces the use of BLKmode for packed records that don't completely fill a mode. * gcc.dg/pr17112-1.c: New test case. Co-Authored-By: Giovanni Bajo <giovannibajo@gcc.gnu.org> From-SVN: r88130
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/stor-layout.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr17112-1.c32
4 files changed, 53 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index af865b1..75ba5a7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,13 @@
2004-09-26 Roger Sayle <roger@eyesopen.com>
+ Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR middle-end/17112
+ * stor-layout.c (compute_record_mode): For records with a single
+ field, only use the field's mode if its size matches what we'd
+ have choosen for the record ourselves. This forces the use of
+ BLKmode for packed records that don't completely fill a mode.
+
+2004-09-26 Roger Sayle <roger@eyesopen.com>
PR middle-end/17151
* combine.c (force_to_mode): Remove dubious early return test that
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index ccbca42..4ac9340 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -1296,12 +1296,14 @@ compute_record_mode (tree type)
#endif /* MEMBER_TYPE_FORCES_BLK */
}
- /* If we only have one real field; use its mode. This only applies to
- RECORD_TYPE. This does not apply to unions. */
- if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode)
+ TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
+
+ /* If we only have one real field; use its mode if that mode's size
+ matches the type's size. This only applies to RECORD_TYPE. This
+ does not apply to unions. */
+ if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
+ && GET_MODE_SIZE (mode) == GET_MODE_SIZE (TYPE_MODE (type)))
TYPE_MODE (type) = mode;
- else
- TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
/* If structure's known alignment is less than what the scalar
mode would need, and it matters, then stick with BLKmode. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 32c3d51..f6ac25c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-09-26 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/17112
+ * gcc.dg/pr17112-1.c: New test case.
+
2004-09-26 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/11459
diff --git a/gcc/testsuite/gcc.dg/pr17112-1.c b/gcc/testsuite/gcc.dg/pr17112-1.c
new file mode 100644
index 0000000..7c8b7aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr17112-1.c
@@ -0,0 +1,32 @@
+/* PR middle-end/17112 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort(void);
+
+typedef struct {
+ int int24:24 __attribute__ ((packed));
+} myint24;
+
+myint24 x[3] = {
+ 0x123456,
+ 0x789abc,
+ 0xdef012
+};
+
+myint24 y[3]; // starts out as zeros
+
+void foo()
+{
+ y[1] = x[1];
+}
+
+int main()
+{
+ foo();
+
+ if (y[0].int24 != 0 || y[2].int24 != 0)
+ abort();
+ return 0;
+}
+