diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c443c467fb6099b79ed4e109ba5c421c5b04222..13974184acd4e2bad1eb3096dc30a38db86317b5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-03-04  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/43164
+	PR tree-optimization/43191
+	* tree-sra.c (type_consists_of_records_p): Reject records with
+	zero-size bit-fields at the end.
+
 2010-03-04  Mike Stump  <mikestump@comcast.net>
 
 	* Makefile.in (TAGS): Remove *.y.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1d382f160c3b5399999f0d61db1b9e10d6db8e61..ca2b87539efc9b8ee2f9033aca4ccc5618a57d03 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2010-03-04  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/43164
+	PR tree-optimization/43191
+	* gcc.c-torture/compile/pr43164.c: New test.
+	* gcc.c-torture/compile/pr43191.c: Likewise.
+
 2010-03-04  Janus Weil  <janus@gcc.gnu.org>
 
 	PR fortran/43244
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43164.c b/gcc/testsuite/gcc.c-torture/compile/pr43164.c
new file mode 100644
index 0000000000000000000000000000000000000000..7e3e074bbccd7024ffc2179159ca28eb4c3ec682
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr43164.c
@@ -0,0 +1,16 @@
+struct S0
+{
+  unsigned char f0;
+  int:0;
+};
+
+struct S1
+{
+  struct S0 f0;
+};
+
+struct S1 func_34 (void)
+{
+  struct S1 l_221 = { { 1 } };
+  return l_221;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43191.c b/gcc/testsuite/gcc.c-torture/compile/pr43191.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c8d1444cf9742b47ebf8fcea0c09731b9e4c401
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr43191.c
@@ -0,0 +1,46 @@
+struct S0
+{
+};
+
+struct S1
+{
+  unsigned f0:27;
+  const unsigned:0;
+};
+
+struct S2
+{
+  unsigned f2:1;
+};
+
+unsigned char g_4[1][8][3][1][1][1];
+unsigned char *g_17;
+unsigned char **g_16[1][10][7];
+
+struct S2 g_35 = {
+  0
+};
+
+struct S2 *g_34 = &g_35;
+
+struct S1 func_86 (unsigned char p_87, struct S2 **p_89)
+{
+  struct S1 l_92[6][8][1][1] = {
+    16143586
+  }
+  ;
+  return l_92[0][0][0][0];
+}
+
+void func_28 (struct S1 p_30, const struct S1 p_32)
+{
+}
+
+void func_70 (unsigned char p_72)
+{
+  unsigned char *const *l_93 = &g_17;
+  struct S2 **l_94;
+  unsigned char *const *l_97 = &g_17;
+  func_28 (func_86 (p_72, 0),
+           func_86 (p_72, &g_34));
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 86620e0f12ba8ab2dc0be9a8f1c77ed3fe1c1213..d32ef387d19e021bc769717c099be94eb8f72abb 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -802,13 +802,15 @@ create_access (tree expr, gimple stmt, bool write)
 
 
 /* Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple
-   register types or (recursively) records with only these two kinds of
-   fields.  */
+   register types or (recursively) records with only these two kinds of fields.
+   It also returns false if any of these records has a zero-size field as its
+   last field.  */
 
 static bool
 type_consists_of_records_p (tree type)
 {
   tree fld;
+  bool last_fld_has_zero_size = false;
 
   if (TREE_CODE (type) != RECORD_TYPE)
     return false;
@@ -821,7 +823,13 @@ type_consists_of_records_p (tree type)
 	if (!is_gimple_reg_type (ft)
 	    && !type_consists_of_records_p (ft))
 	  return false;
+
+	last_fld_has_zero_size = tree_low_cst (DECL_SIZE (fld), 1) == 0;
       }
+
+  if (last_fld_has_zero_size)
+    return false;
+
   return true;
 }