===================================================================
@@ -4705,6 +4705,22 @@ expand_assignment (tree to, tree from, b
to_rtx = adjust_address (to_rtx, mode1, 0);
else if (GET_MODE (to_rtx) == VOIDmode)
to_rtx = adjust_address (to_rtx, BLKmode, 0);
+ /* If the alignment of tem is larger than its size and we
+ are performing a bitfield access limit the mode we use
+ for the access to make sure we do not access the decl
+ beyond its end. See PR48124. */
+ else if (GET_MODE (to_rtx) == BLKmode
+ && mode1 == VOIDmode
+ && DECL_P (tem)
+ && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST
+ && (TREE_INT_CST_LOW (DECL_SIZE (tem))
+ & (DECL_ALIGN (tem) - 1)) != 0)
+ {
+ unsigned HOST_WIDE_INT mis;
+ mis = TREE_INT_CST_LOW (DECL_SIZE (tem)) & (DECL_ALIGN (tem) - 1);
+ mode1 = mode_for_size (mis & -mis, MODE_INT, 0);
+ to_rtx = adjust_address (to_rtx, mode1, 0);
+ }
}
if (offset != 0)
===================================================================
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-fno-toplevel-reorder" } */
+
+extern void abort (void);
+
+struct S
+{
+ signed a : 26;
+ signed b : 16;
+ signed c : 10;
+ volatile signed d : 14;
+};
+
+static struct S e = { 0, 0, 0, 1 };
+static int f = 1;
+
+void __attribute__((noinline))
+foo (void)
+{
+ e.d = 0;
+ f = 2;
+}
+
+int
+main ()
+{
+ if (e.a || e.b || e.c || e.d != 1 || f != 1)
+ abort ();
+ foo ();
+ if (e.a || e.b || e.c || e.d || f != 2)
+ abort ();
+ return 0;
+}
===================================================================
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+static volatile struct S0 {
+ short f3[9];
+ unsigned f8 : 15;
+} s = {1};
+static unsigned short sh = 0x1234;
+
+struct S0 a, b;
+int vi = 0;
+
+void func_4()
+{
+ s.f8 |= 1;
+ sh = 15;
+ if (vi) a = b;
+}
+
+int main()
+{
+ func_4();
+ if (sh != 15)
+ abort ();
+ return 0;
+}
===================================================================
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+
+extern void abort (void);
+struct S1
+{
+ int f0;
+ int:1;
+ int f3;
+ int:1;
+ int:0;
+ int f6:1;
+};
+int g_13 = 1;
+volatile struct S1 g_118 = {
+ 1
+};
+
+void __attribute__((noinline))
+func_46 ()
+{
+ for (g_13 = 0; g_13 >= 0; g_13 -= 1)
+ g_118.f6 = 0;
+}
+
+int
+main ()
+{
+ func_46 ();
+ if (g_13 != -1)
+ abort ();
+ return 0;
+}