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] Fix finish_struct (take 2)


On Fri, Aug 15, 2003 at 01:12:46AM +0200, Jakub Jelinek wrote:
> Hi!
> 
> I cannot find anywhere setting of prev in finish_struct other than
> clearing it initially.  This means prev is always NULL and thus any
> type which is completed will result in setting current_scope->incomplete
> to the type after it.  If there were some types which are still incomplete
> before, this IMHO means they are lost and never completed.
> Unless I'm too sleepy something like this is needed (will try to cook up
> a testcase tomorrow to verify).

Indeed, the following testcase fails without the patch (and succeeds
in gcc 3.2.x and with the patch).
I've also noticed that pushdecl chains even decls which will never be
handled by finish_struct (like e.g. incomplete typedef struct a E;),
which means that we waste memory and make the list longer than it ought
to be.
Ok to commit? 3.3 branch as well?

2003-08-15  Jakub Jelinek  <jakub@redhat.com>

	* c-decl.c (pushdecl): Remove obsolete comment.
	Only put decls which finish_struct will do something about onto
	incomplete chain.
	(finish_struct): If not removing type from incomplete
	list, update prev.

	* gcc.dg/20030815-1.c: New test.

--- gcc/c-decl.c.jj	2003-08-05 18:41:16.000000000 -0400
+++ gcc/c-decl.c	2003-08-15 04:30:01.000000000 -0400
@@ -1747,11 +1747,7 @@ pushdecl (tree x)
       /* Keep list of variables in this scope with incomplete type.
 	 If the input is erroneous, we can have error_mark in the type
 	 slot (e.g. "f(void a, ...)") - that doesn't count as an
-	 incomplete type.
-
-	 FIXME: Chain these off the TYPE_DECL for the incomplete type,
-	 then we don't have to do (potentially quite costly) searches
-	 in finish_struct.  */
+	 incomplete type.  */
       if (TREE_TYPE (x) != error_mark_node
 	  && !COMPLETE_TYPE_P (TREE_TYPE (x)))
 	{
@@ -1759,8 +1755,10 @@ pushdecl (tree x)
 
 	  while (TREE_CODE (element) == ARRAY_TYPE)
 	    element = TREE_TYPE (element);
-	  if (TREE_CODE (element) == RECORD_TYPE
-	      || TREE_CODE (element) == UNION_TYPE)
+	  if ((TREE_CODE (element) == RECORD_TYPE
+	       || TREE_CODE (element) == UNION_TYPE)
+	      && (TREE_CODE (x) != TYPE_DECL
+		  || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE))
 	    scope->incomplete = tree_cons (NULL_TREE, x, scope->incomplete);
 	}
     }
@@ -5152,7 +5150,8 @@ finish_struct (tree t, tree fieldlist, t
 	      && TREE_CODE (decl) != TYPE_DECL)
 	    {
 	      layout_decl (decl, 0);
-	      /* This is a no-op in c-lang.c or something real in objc-act.c.  */
+	      /* This is a no-op in c-lang.c or something real in
+		 objc-act.c.  */
 	      if (c_dialect_objc ())
 		objc_check_decl (decl);
 	      rest_of_decl_compilation (decl, NULL, toplevel, 0);
@@ -5188,7 +5187,11 @@ finish_struct (tree t, tree fieldlist, t
 		  else
 		    current_scope->incomplete = TREE_CHAIN (x);
 		}
+	      else
+		prev = x;
 	    }
+	  else
+	    prev = x;
 	}
     }
 
--- gcc/testsuite/gcc.dg/20030815-1.c.jj	2003-08-15 04:09:12.000000000 -0400
+++ gcc/testsuite/gcc.dg/20030815-1.c	2003-08-15 04:22:06.000000000 -0400
@@ -0,0 +1,26 @@
+/* Test completion of incomplete types.
+   There used to be a bug where some types from incomplete
+   list were accidentally lost.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+typedef struct a A[1];
+typedef struct b B[1];
+typedef struct c C[1];
+typedef struct d D[1];
+typedef struct a E;
+typedef struct b F;
+typedef struct c G;
+typedef struct d H;
+struct a { int a; };
+struct c { int c; };
+struct d { int d; };
+struct b { int b; };
+int sa = sizeof (A);
+int sb = sizeof (B);
+int sc = sizeof (C);
+int sd = sizeof (D);
+int se = sizeof (E);
+int sf = sizeof (F);
+int sg = sizeof (G);
+int sh = sizeof (H);

	Jakub


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