--- gcc/expmed.c.orig	2013-10-25 11:06:31.462212259 +0200
+++ gcc/expmed.c	2013-10-25 13:53:33.706343572 +0200
@@ -416,12 +416,17 @@ lowpart_bit_field_p (unsigned HOST_WIDE_
 }
 
 /* Return true if -fstrict-volatile-bitfields applies an access of OP0
-   containing BITSIZE bits starting at BITNUM, with field mode FIELDMODE.  */
+   containing BITSIZE bits starting at BITNUM, with field mode FIELDMODE.
+   Return false if the access would touch memory outside the range
+   BITREGION_START to BITREGION_END for conformance to the C++ memory
+   model.  */
 
 static bool
 strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
 			    unsigned HOST_WIDE_INT bitnum,
-			    enum machine_mode fieldmode)
+			    enum machine_mode fieldmode,
+			    unsigned HOST_WIDE_INT bitregion_start,
+			    unsigned HOST_WIDE_INT bitregion_end)
 {
   unsigned HOST_WIDE_INT modesize = GET_MODE_BITSIZE (fieldmode);
 
@@ -448,6 +453,12 @@ strict_volatile_bitfield_p (rtx op0, uns
 	  && bitnum % GET_MODE_ALIGNMENT (fieldmode) + bitsize > modesize))
     return false;
 
+  /* Check for cases where the C++ memory model applies.  */
+  if (bitregion_end != 0
+      && (bitnum - bitnum % modesize < bitregion_start
+	  || bitnum - bitnum % modesize + modesize > bitregion_end))
+    return false;
+
   return true;
 }
 
@@ -904,7 +915,8 @@ store_bit_field (rtx str_rtx, unsigned H
 		 rtx value)
 {
   /* Handle -fstrict-volatile-bitfields in the cases where it applies.  */
-  if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, fieldmode))
+  if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, fieldmode,
+				  bitregion_start, bitregion_end))
     {
 
       /* Storing any naturally aligned field can be done with a simple
@@ -1699,6 +1711,14 @@ extract_bit_field (rtx str_rtx, unsigned
 {
   enum machine_mode mode1;
 
+  /* Handle extraction of unaligned fields,
+     this can happen in -fstrict-volatile-bitfields.  */
+  if (GET_MODE_BITSIZE (GET_MODE (str_rtx)) != 0
+      && GET_MODE_BITSIZE (GET_MODE (str_rtx)) < GET_MODE_BITSIZE (word_mode)
+      && bitnum % GET_MODE_BITSIZE (GET_MODE (str_rtx)) + bitsize
+	 > GET_MODE_BITSIZE (GET_MODE (str_rtx)) )
+    str_rtx = adjust_address (str_rtx, word_mode, 0);
+
   /* Handle -fstrict-volatile-bitfields in the cases where it applies.  */
   if (GET_MODE_BITSIZE (GET_MODE (str_rtx)) > 0)
     mode1 = GET_MODE (str_rtx);
@@ -1707,7 +1727,7 @@ extract_bit_field (rtx str_rtx, unsigned
   else
     mode1 = tmode;
 
-  if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, mode1))
+  if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, mode1, 0, 0))
     {
       rtx result;
 
--- gcc/testsuite/gcc.dg/pr23623.c.orig	2013-10-26 23:28:41.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr23623.c	2013-10-26 23:26:49.000000000 +0200
@@ -8,16 +8,19 @@
 extern struct
 {
   unsigned int b : 1;
+  unsigned int : 31;
 } bf1;
 
 extern volatile struct
 {
   unsigned int b : 1;
+  unsigned int : 31;
 } bf2;
 
 extern struct
 {
   volatile unsigned int b : 1;
+  volatile unsigned int : 31;
 } bf3;
 
 void writeb(void)
