This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for bug 21873


This patch fixes bug 21873, an infinite loop in the C front end
warning for an initializer for a size 0 array.  There proved to be
lots of related cases which yield infinite loops (some with
diagnostics, some silent) or ICEs with all compilers back to 3.0.x,
but 2.95.3 compiles the included testcase in finite time without ICE
so this is a regression.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Applied
to mainline and 4.0 branch.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-06-04  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/21873
	* c-typeck.c (push_init_level): Don't pop levels without braces if
	implicit == 1.

testsuite:
2005-06-04  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/21873
	* gcc.dg/init-excess-1.c: New test.

diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-06-03 10:45:45.000000000 +0000
+++ GCC/gcc/c-typeck.c	2005-06-03 23:22:59.000000000 +0000
@@ -4844,19 +4844,27 @@ push_init_level (int implicit)
   tree value = NULL_TREE;
 
   /* If we've exhausted any levels that didn't have braces,
-     pop them now.  */
-  while (constructor_stack->implicit)
+     pop them now.  If implicit == 1, this will have been done in
+     process_init_element; do not repeat it here because in the case
+     of excess initializers for an empty aggregate this leads to an
+     infinite cycle of popping a level and immediately recreating
+     it.  */
+  if (implicit != 1)
     {
-      if ((TREE_CODE (constructor_type) == RECORD_TYPE
-	   || TREE_CODE (constructor_type) == UNION_TYPE)
-	  && constructor_fields == 0)
-	process_init_element (pop_init_level (1));
-      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
-	       && constructor_max_index
-	       && tree_int_cst_lt (constructor_max_index, constructor_index))
-	process_init_element (pop_init_level (1));
-      else
-	break;
+      while (constructor_stack->implicit)
+	{
+	  if ((TREE_CODE (constructor_type) == RECORD_TYPE
+	       || TREE_CODE (constructor_type) == UNION_TYPE)
+	      && constructor_fields == 0)
+	    process_init_element (pop_init_level (1));
+	  else if (TREE_CODE (constructor_type) == ARRAY_TYPE
+		   && constructor_max_index
+		   && tree_int_cst_lt (constructor_max_index,
+				       constructor_index))
+	    process_init_element (pop_init_level (1));
+	  else
+	    break;
+	}
     }
 
   /* Unless this is an explicit brace, we need to preserve previous
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/init-excess-1.c GCC/gcc/testsuite/gcc.dg/init-excess-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/init-excess-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/init-excess-1.c	2005-06-03 22:39:59.000000000 +0000
@@ -0,0 +1,48 @@
+/* Test for various cases of excess initializers for empty objects:
+   bug 21873.  Various versions of GCC ICE, hang or loop repeating
+   diagnostics on various of these tests.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct s0 { };
+struct s1 { int a; };
+struct s2 { int a; int b; };
+
+int a0[0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a1[0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a2[0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a3[1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a4[][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a5[][0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a6[][0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+int a7[][1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+
+struct s0 b0[0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b1[0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b2[0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b3[1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b4[][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b5[][0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b6[][0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b7[][1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b8[1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s0 b9[] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+
+struct s1 c0[0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c1[0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c2[0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c3[1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c4[][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c5[][0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c6[][0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s1 c7[][1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+
+struct s2 d0[0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d1[0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d2[0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d3[1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d4[][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d5[][0][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d6[][0][1] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */
+struct s2 d7[][1][0] = { 1, 2 }; /* { dg-warning "excess elements|near init" } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]