C++ PATCH: PR 14476

Mark Mitchell mark@codesourcery.com
Thu Mar 11 08:43:00 GMT 2004


This patch fixes an error-recovery ICE regression.  The problem was
that -- for error recovery -- we created an enumeration type with no
TYPE_SIZE, which caused crashes later on, since parts of the compiler
make the (valid in C++) assumption that there is no such thing as an
incomplete enumeration type.  At first, I tried calling layout_type on
the dummy type, so that it would have a size, but that lead to a weird
error cascade: different choices of min/max enumeral for the dummy
type lead to different warnings when used in different contexts.

So, let's just not be so clever: if an undefined enumeration type is
used, just don't create a dummy type.

Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-03-11  Mark Mitchell  <mark@codesourcery.com>

	PR c++/14476
	* decl.c (xref_tag): Do not create dummy ENUMERAL_TYPEs.

2004-03-11  Mark Mitchell  <mark@codesourcery.com>

	PR c++/14476
	* g++.dg/lookup/enum1.C: New test. 

Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1174.2.13
diff -c -5 -p -r1.1174.2.13 decl.c
*** cp/decl.c	11 Mar 2004 04:08:02 -0000	1.1174.2.13
--- cp/decl.c	11 Mar 2004 08:30:00 -0000
*************** xref_tag (enum tag_types tag_code, tree 
*** 9446,9474 ****
  	 When a real declaration of this type is found,
  	 the forward-reference will be altered into a real type.  */
        if (code == ENUMERAL_TYPE)
  	{
  	  error ("use of enum `%#D' without previous declaration", name);
! 
! 	  t = make_node (ENUMERAL_TYPE);
! 
! 	  /* Give the type a default layout like unsigned int
! 	     to avoid crashing if it does not get defined.  */
! 	  TYPE_MODE (t) = TYPE_MODE (unsigned_type_node);
! 	  TYPE_ALIGN (t) = TYPE_ALIGN (unsigned_type_node);
! 	  TYPE_USER_ALIGN (t) = 0;
! 	  TREE_UNSIGNED (t) = 1;
! 	  TYPE_PRECISION (t) = TYPE_PRECISION (unsigned_type_node);
! 	  TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (unsigned_type_node);
! 	  TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (unsigned_type_node);
! 
! 	  /* Enable us to recognize when a type is created in class context.
! 	     To do nested classes correctly, this should probably be cleared
! 	     out when we leave this classes scope.  Currently this in only
! 	     done in `start_enum'.  */
! 
! 	  pushtag (name, t, globalize);
  	}
        else
  	{
  	  t = make_aggr_type (code);
  	  TYPE_CONTEXT (t) = context;
--- 9446,9456 ----
  	 When a real declaration of this type is found,
  	 the forward-reference will be altered into a real type.  */
        if (code == ENUMERAL_TYPE)
  	{
  	  error ("use of enum `%#D' without previous declaration", name);
! 	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	}
        else
  	{
  	  t = make_aggr_type (code);
  	  TYPE_CONTEXT (t) = context;
Index: testsuite/g++.dg/lookup/enum1.C
===================================================================
RCS file: testsuite/g++.dg/lookup/enum1.C
diff -N testsuite/g++.dg/lookup/enum1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/lookup/enum1.C	11 Mar 2004 08:37:43 -0000
***************
*** 0 ****
--- 1,5 ----
+ // PR c++/14476
+ 
+ struct tree_common {
+   enum tree_code code : 8; // { dg-error "" }
+ };



More information about the Gcc-patches mailing list