diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 80f588d15beb6bdaa773e94fc33cf1d94718c762..8f4c296bb56d58251ec74b07d49d1d5582a38fd0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2006-06-05  Joseph S. Myers  <joseph@codesourcery.com>
+
+	PR c/25161
+	PR c/27020
+	* c-decl.c (grokdeclarator): Disallow variably modified types at
+	file scope.  Avoid marking shared array type of constant size as
+	VLA.
+
 2006-06-04  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
 	PR c++/27601
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index ddf068a74f30c46ce340f31ad4c4f4f49927bf4c..22b6dabcffa89cf422809bd89438674e4e9622f7 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -3936,6 +3936,14 @@ grokdeclarator (const struct c_declarator *declarator,
   if (declspecs->deprecated_p && deprecated_state != DEPRECATED_SUPPRESS)
     warn_deprecated_use (declspecs->type);
 
+  if ((decl_context == NORMAL || decl_context == FIELD)
+      && current_scope == file_scope
+      && variably_modified_type_p (type, NULL_TREE))
+    {
+      error ("variably modified %qs at file scope", name);
+      type = integer_type_node;
+    }
+
   typedef_type = type;
   size_varies = C_TYPE_VARIABLE_SIZE (type);
 
@@ -4206,6 +4214,12 @@ grokdeclarator (const struct c_declarator *declarator,
 			size = integer_one_node;
 		      }
 		  }
+		else if ((decl_context == NORMAL || decl_context == FIELD)
+			 && current_scope == file_scope)
+		  {
+		    error ("variably modified %qs at file scope", name);
+		    size = integer_one_node;
+		  }
 		else
 		  {
 		    /* Make sure the array size remains visibly
@@ -4304,7 +4318,12 @@ grokdeclarator (const struct c_declarator *declarator,
 	    if (type != error_mark_node)
 	      {
 		if (size_varies)
-		  C_TYPE_VARIABLE_SIZE (type) = 1;
+		  {
+		    if (size && TREE_CODE (size) == INTEGER_CST)
+		      type
+			= build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
+		    C_TYPE_VARIABLE_SIZE (type) = 1;
+		  }
 
 		/* The GCC extension for zero-length arrays differs from
 		   ISO flexible array members in that sizeof yields
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 46095299fff2c0049393515d5116ba3b24a2e9f8..07c75be3173e69c4b6cc387430f867b6b075e267 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2006-06-05  Joseph S. Myers  <joseph@codesourcery.com>
+
+	PR c/25161
+	PR c/27020
+	* gcc.dg/array-10.c: New test.
+
 2006-06-05  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
 	PR c++/27804
diff --git a/gcc/testsuite/gcc.dg/array-10.c b/gcc/testsuite/gcc.dg/array-10.c
new file mode 100644
index 0000000000000000000000000000000000000000..aab1538d5e16743bad0be8792623499ac6e0afca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/array-10.c
@@ -0,0 +1,33 @@
+/* Test invalid array sizes at file scope: should not cause ICEs.
+   Bugs 25161 and 27020.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int a;
+
+int b0[a]; /* { dg-error "at file scope" } */
+int (*b1)[a]; /* { dg-error "at file scope" } */
+int (*b2())[a]; /* { dg-error "at file scope" } */
+struct b3 { int x[a]; }; /* { dg-error "at file scope" } */
+struct b4 { int (*x)[a]; }; /* { dg-error "at file scope" } */
+typeof (int [a]) b5; /* { dg-error "at file scope|outside of any function" } */
+
+int c0[(__SIZE_TYPE__)&a]; /* { dg-error "at file scope" } */
+int (*c1)[(__SIZE_TYPE__)&a]; /* { dg-error "at file scope" } */
+int (*c2())[(__SIZE_TYPE__)&a]; /* { dg-error "at file scope" } */
+struct c3 { int x[(__SIZE_TYPE__)&a]; }; /* { dg-error "at file scope" } */
+struct c4 { int (*x)[(__SIZE_TYPE__)&a]; }; /* { dg-error "at file scope" } */
+typeof (int [(__SIZE_TYPE__)&a]) c5; /* { dg-error "at file scope" } */
+
+int d0[1/0]; /* { dg-error "at file scope" } */
+/* { dg-warning "division by zero" "" { target *-*-* } 23 } */
+int (*d1)[1/0]; /* { dg-error "at file scope" } */
+/* { dg-warning "division by zero" "" { target *-*-* } 25 } */
+int (*d2())[1/0]; /* { dg-error "at file scope" } */
+/* { dg-warning "division by zero" "" { target *-*-* } 27 } */
+struct d3 { int x[1/0]; }; /* { dg-error "at file scope" } */
+/* { dg-warning "division by zero" "" { target *-*-* } 29 } */
+struct d4 { int (*x)[1/0]; }; /* { dg-error "at file scope" } */
+/* { dg-warning "division by zero" "" { target *-*-* } 31 } */
+typeof (int [1/0]) d5; /* { dg-error "at file scope" } */