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]

C++ PATCH: PR c++/10428


This patch fixes a C++ regression whereby we accepted, but crashed, on
the (invalid) use of a typedef-name in an elaborated-type-specifier.

--
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery dot com

2003-04-22  Mark Mitchell  <mark at codesourcery dot com>

	PR c++/10428
	* g++.dg/parse/elab1.C: New test.

2003-04-22  Mark Mitchell  <mark at codesourcery dot com>

	PR c++/10428
	* decl.c (check_elaborated_type_specifier): New function, split
	out from ...
	(xref_tag): ... here.  Use the new function in more places.

Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1038
diff -c -5 -p -r1.1038 decl.c
*** cp/decl.c	22 Apr 2003 05:44:08 -0000	1.1038
--- cp/decl.c	22 Apr 2003 21:01:24 -0000
*************** tag_name (enum tag_types code)
*** 12523,12532 ****
--- 12523,12564 ----
      default:
        abort ();
      }
  }
  
+ /* Name lookup in an elaborated-type-specifier (after the keyword
+    indicated by TAG_CODE) has found TYPE.  If the
+    elaborated-type-specifier is invalid, issue a diagnostic and return
+    error_mark_node; otherwise, return TYPE itself.  */
+ 
+ static tree
+ check_elaborated_type_specifier (enum tag_types tag_code,
+ 				 tree type)
+ {
+   tree t;
+ 
+   t = follow_tag_typedef (type);
+ 
+   /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
+      template type-parameter, the elaborated-type-specifier is
+      ill-formed.  */
+   if (!t)
+     {
+       error ("using typedef-name `%D' after `%s'",
+ 	     TYPE_NAME (type), tag_name (tag_code));
+       t = error_mark_node;
+     }
+   else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+     {
+       error ("using template type parameter `%T' after `%s'",
+ 	     type, tag_name (tag_code));
+       t = error_mark_node;
+     }
+ 
+   return t;
+ }
+ 
  /* Get the struct, enum or union (CODE says which) with tag NAME.
     Define the tag as a forward-reference if it is not defined.
  
     C++: If a class derivation is given, process it here, and report
     an error if multiple derivation declarations are not identical.
*************** xref_tag (enum tag_types tag_code, tree 
*** 12609,12632 ****
      }
    else
      {
        if (t)
  	{
! 	  ref = follow_tag_typedef (t);
! 
! 	  /* [dcl.type.elab] If the identifier resolves to a
! 	     typedef-name or a template type-parameter, the
! 	     elaborated-type-specifier is ill-formed.  */
! 	  if (!ref)
! 	    {
! 	      pedwarn ("using typedef-name `%D' after `%s'",
! 		       TYPE_NAME (t), tag_name (tag_code));
! 	      ref = t;
! 	    }
! 	  else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
! 	    error ("using template type parameter `%T' after `%s'",
! 		   t, tag_name (tag_code));
  	}
        else
  	ref = lookup_tag (code, name, b, 0);
  
        if (! ref)
--- 12641,12653 ----
      }
    else
      {
        if (t)
  	{
! 	  ref = check_elaborated_type_specifier (tag_code, t);
! 	  if (ref == error_mark_node)
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	}
        else
  	ref = lookup_tag (code, name, b, 0);
  
        if (! ref)
*************** xref_tag (enum tag_types tag_code, tree 
*** 12641,12653 ****
  	      && template_class_depth (current_class_type) == 0)
  	    /* Since GLOBALIZE is true, we're declaring a global
  	       template, so we want this type.  */
  	    ref = DECL_TEMPLATE_RESULT (ref);
  
! 	  if (ref && TREE_CODE (ref) == TYPE_DECL
! 	      && TREE_CODE (TREE_TYPE (ref)) == code)
! 	    ref = TREE_TYPE (ref);
  	  else
  	    ref = NULL_TREE;
  	}
  
        if (ref && current_class_type
--- 12662,12680 ----
  	      && template_class_depth (current_class_type) == 0)
  	    /* Since GLOBALIZE is true, we're declaring a global
  	       template, so we want this type.  */
  	    ref = DECL_TEMPLATE_RESULT (ref);
  
! 	  if (ref && TREE_CODE (ref) == TYPE_DECL)
! 	    {
! 	      ref = check_elaborated_type_specifier (tag_code, 
! 						     TREE_TYPE (ref));
! 	      if (ref == error_mark_node)
! 		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
! 	      if (ref && TREE_CODE (ref) != code)
! 		ref = NULL_TREE;
! 	    }
  	  else
  	    ref = NULL_TREE;
  	}
  
        if (ref && current_class_type
Index: testsuite/g++.dg/parse/elab1.C
===================================================================
RCS file: testsuite/g++.dg/parse/elab1.C
diff -N testsuite/g++.dg/parse/elab1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/elab1.C	22 Apr 2003 21:01:31 -0000
***************
*** 0 ****
--- 1,9 ----
+ namespace Name {
+ 
+     typedef void *(*Function)( void *, int );
+ 
+     struct Foo {
+       struct Function xyz[5]; // { dg-error "" }
+     };
+ 
+ }


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