re PR middle-end/17112 (Copying of packed bitfields is wrong)
authorRoger Sayle <roger@eyesopen.com>
Sun, 26 Sep 2004 14:58:34 +0000 (14:58 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sun, 26 Sep 2004 14:58:34 +0000 (14:58 +0000)
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

gcc/ChangeLog
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr17112-1.c [new file with mode: 0644]

index af865b184776747b0941b56e94d7a589d8d0dfd9..75ba5a7163f9a8948148eff3087655c6b588ce08 100644 (file)
@@ -1,3 +1,12 @@
+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
index ccbca424bbfb128eb8f646284a88f194fed5e80c..4ac93404a8e62533071d191ce71ce566a2be85f3 100644 (file)
@@ -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.  */
index 32c3d51a555aa67a88ae2c74e13598e97910ee76..f6ac25c0f07f4404f154881a223db4fb809a9a56 100644 (file)
@@ -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 (file)
index 0000000..7c8b7aa
--- /dev/null
@@ -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;
+}
+