3.4 backports of patches for bugs 21873 and 21899

Joseph S. Myers joseph@codesourcery.com
Thu Jul 28 23:02:00 GMT 2005


I've applied the following patches to 3.4 branch to fix regression bugs 
21873 and 21899.  (The latter is a backport of my patch for bug 17188 
which fixed 21899 on mainline, so 17188 is now fixed on 3.4 branch as 
well.)  Bootstrapped with no regressions on x86_64-unknown-linux-gnu.

-- 
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-07-28  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-07-28  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.21873/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-01-19 09:44:35.000000000 +0000
+++ GCC.21873/gcc/c-typeck.c	2005-07-28 21:26:24.000000000 +0000
@@ -4634,19 +4634,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.21873/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.21873/gcc/testsuite/gcc.dg/init-excess-1.c	2005-07-28 21:26:24.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" } */

2005-07-28  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/17188
	PR c/21899
	* c-decl.c (diagnose_mismatched_decls): Check for duplicate
	declarations of enumerators.
	(start_struct): Check TYPE_SIZE rather than TYPE_FIELDS to check
	for redefinition.  Check for nested redefinition.
	(finish_struct): Don't check for nested redefinition.
	(start_enum): Check for nested redefinition.

testsuite:
2005-07-28  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/17188
	PR c/21899
	* gcc.dg/nested-redef-1.c, gcc.dg/pr17188-1.c: New tests.
	* gcc.dg/decl-3.c: Adjust expected message.

diff -rupN GCC.orig/gcc/c-decl.c GCC.21899/gcc/c-decl.c
--- GCC.orig/gcc/c-decl.c	2005-07-05 21:19:02.000000000 +0000
+++ GCC.21899/gcc/c-decl.c	2005-07-28 21:27:44.000000000 +0000
@@ -955,6 +955,15 @@ diagnose_mismatched_decls (tree newdecl,
       return false;
     }
 
+  /* Enumerators have no linkage, so may only be declared once in a
+     given scope.  */
+  if (TREE_CODE (olddecl) == CONST_DECL)
+    {
+      error ("%Jredeclaration of enumerator `%D'", newdecl, newdecl);
+      locate_old_decl (olddecl, error);
+      return false;
+    }
+
   if (!comptypes (oldtype, newtype, COMPARE_STRICT))
     {
       if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -4779,13 +4788,22 @@ start_struct (enum tree_code code, tree 
     ref = lookup_tag (code, name, 1);
   if (ref && TREE_CODE (ref) == code)
     {
-      if (TYPE_FIELDS (ref))
+      if (TYPE_SIZE (ref))
         {
 	  if (code == UNION_TYPE)
 	    error ("redefinition of `union %s'", IDENTIFIER_POINTER (name));
           else
 	    error ("redefinition of `struct %s'", IDENTIFIER_POINTER (name));
 	}
+      else if (C_TYPE_BEING_DEFINED (ref))
+	{
+	  if (code == UNION_TYPE)
+	    error ("nested redefinition of `union %s'",
+		   IDENTIFIER_POINTER (name));
+          else
+	    error ("nested redefinition of `struct %s'",
+		   IDENTIFIER_POINTER (name));
+	}
     }
   else
     {
@@ -5000,11 +5018,6 @@ finish_struct (tree t, tree fieldlist, t
       if (C_DECL_VARIABLE_SIZE (x))
 	C_TYPE_VARIABLE_SIZE (t) = 1;
 
-      /* Detect invalid nested redefinition.  */
-      if (TREE_TYPE (x) == t)
-	error ("nested redefinition of `%s'",
-	       IDENTIFIER_POINTER (TYPE_NAME (t)));
-
       if (DECL_INITIAL (x))
 	{
 	  unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1);
@@ -5202,6 +5215,9 @@ start_enum (tree name)
       pushtag (name, enumtype);
     }
 
+  if (C_TYPE_BEING_DEFINED (enumtype))
+    error ("nested redefinition of `enum %s'", IDENTIFIER_POINTER (name));
+
   C_TYPE_BEING_DEFINED (enumtype) = 1;
 
   if (TYPE_VALUES (enumtype) != 0)
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/decl-3.c GCC.21899/gcc/testsuite/gcc.dg/decl-3.c
--- GCC.orig/gcc/testsuite/gcc.dg/decl-3.c	2004-01-11 01:18:58.000000000 +0000
+++ GCC.21899/gcc/testsuite/gcc.dg/decl-3.c	2005-07-28 21:26:28.000000000 +0000
@@ -2,4 +2,4 @@
 /* { dg-do compile } */
 
 enum { CODES }; /* { dg-error "previous definition" } */
-enum { CODES }; /* { dg-error "conflicting types" } */
+enum { CODES }; /* { dg-error "conflicting types|redeclaration of enumerator" } */
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/nested-redef-1.c GCC.21899/gcc/testsuite/gcc.dg/nested-redef-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/nested-redef-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC.21899/gcc/testsuite/gcc.dg/nested-redef-1.c	2005-07-28 21:26:28.000000000 +0000
@@ -0,0 +1,44 @@
+/* Test diagnosis of nested tag redefinitions.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct s0 {
+  struct s0 { int a; } x; /* { dg-error "error: nested redefinition of `struct s0'" } */
+};
+
+struct s1 {
+  const struct s1 { int b; } x; /* { dg-error "error: nested redefinition of `struct s1'" } */
+};
+
+struct s2 {
+  struct s2 { int c; } *x; /* { dg-error "error: nested redefinition of `struct s2'" } */
+};
+
+struct s3 {
+  struct s4 {
+    struct s5 {
+      struct s3 { int a; } **x; /* { dg-error "error: nested redefinition of `struct s3'" } */
+    } y;
+  } z;
+};
+
+struct s6;
+struct s6 { struct s6 *p; };
+
+union u0 {
+  union u0 { int c; } *x; /* { dg-error "error: nested redefinition of `union u0'" } */
+};
+
+enum e0 {
+  E0 = sizeof(enum e0 { E1 }) /* { dg-error "error: nested redefinition of `enum e0'" } */
+};
+
+enum e1 {
+  E2 = sizeof(enum e2 { E2 }), /* { dg-error "error: redeclaration of enumerator `E2'" } */
+  /* { dg-error "previous definition" "previous E2" { target *-*-* } 38 } */
+  E3
+};
+
+enum e3;
+enum e3 { E4 = 0 };
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/pr17188-1.c GCC.21899/gcc/testsuite/gcc.dg/pr17188-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/pr17188-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC.21899/gcc/testsuite/gcc.dg/pr17188-1.c	2005-07-28 21:26:28.000000000 +0000
@@ -0,0 +1,31 @@
+/* A redefinition of an empty struct should be diagnosed the same as a
+   redefinition of any other tag, but formerly only s2 and s4 were
+   diagnosed.  Bug 17188.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct s0 { };
+struct s0;
+struct s0 { }; /* { dg-error "error: redefinition of `struct s0'" } */
+
+struct s1 { };
+struct s1 { }; /* { dg-error "error: redefinition of `struct s1'" } */
+
+struct s2 { int a : 1; };
+struct s2 { int a : 1; }; /* { dg-error "error: redefinition of `struct s2'" } */
+
+struct s3 { };
+struct s3 { int a : 1; }; /* { dg-error "error: redefinition of `struct s3'" } */
+
+struct s4 { int a : 1; };
+struct s4 { }; /* { dg-error "error: redefinition of `struct s4'" } */
+
+struct s5 { int a : 1; };
+struct s5;
+
+struct s6;
+struct s6 { int a : 1; };
+
+struct s7;
+struct s7 { };



More information about the Gcc-patches mailing list