diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b45e59c549793b15e0b2265ece528d338b5e12f3..89398d7eaf3e33bf1778390cd1fbb36cde715956 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
 2010-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+	PR other/42611
+	* cfgexpand.c (expand_one_var): Diagnose too large variables.
+
 	PR tree-optimization/42508
 	* tree-sra.c (convert_callers): Check for recursive call
 	by comparing cgraph nodes instead of decls.
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b0921bfe8e96ab9bf69adfca9c7a2a3b480a82de..7e542da3320eae90136fb2156267910088c94795 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1,5 +1,5 @@
 /* A pass for lowering trees to RTL.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1011,6 +1011,14 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
       if (really_expand)
         expand_one_register_var (origvar);
     }
+  else if (!host_integerp (DECL_SIZE_UNIT (var), 1))
+    {
+      if (really_expand)
+	{
+	  error ("size of variable %q+D is too large", var);
+	  expand_one_error_var (var);
+	}
+    }
   else if (defer_stack_allocation (var, toplevel))
     add_stack_var (origvar);
   else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89358798c846f124e231a7e7bc5fe0fd9ac461ec..aea6aa18026c60c99daaee6525b67c93390fb75d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2010-01-05  Jakub Jelinek  <jakub@redhat.com>
 
+	PR other/42611
+	* gcc.dg/pr42611.c: New test.
+
 	PR tree-optimization/42508
 	* g++.dg/opt/pr42508.C: New test.
 
diff --git a/gcc/testsuite/gcc.dg/pr42611.c b/gcc/testsuite/gcc.dg/pr42611.c
new file mode 100644
index 0000000000000000000000000000000000000000..c33e248caf500f59da1e3ec42d366c13fbcf6dd1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr42611.c
@@ -0,0 +1,19 @@
+/* PR other/42611 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#define L \
+  (sizeof (__SIZE_TYPE__) == 1 ? __SCHAR_MAX__				\
+  : sizeof (__SIZE_TYPE__) == sizeof (short) ? __SHRT_MAX__		\
+  : sizeof (__SIZE_TYPE__) == sizeof (int) ? __INT_MAX__		\
+  : sizeof (__SIZE_TYPE__) == sizeof (long) ? __LONG_MAX__		\
+  : sizeof (__SIZE_TYPE__) == sizeof (long long) ? __LONG_LONG_MAX__	\
+  : __INTMAX_MAX__)
+struct S { int a; char b[L]; };
+
+void
+foo (void)
+{
+  struct S s;				/* { dg-error "is too large" } */
+  asm volatile ("" : : "r" (&s));
+}