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 for 3.4/4.0] Fix PR18123 template declaration of enum(take 2)


Hi

This is a revised version of

http://gcc.gnu.org/ml/gcc-patches/2004-11/msg00194.html

fixing PR18123 which is a regression on GCC 3.4, 4.0.
This one produces error message immediately rather than
after producing ENUM_TYPE and TYPE_DECL nodes.

For 3.4 version, some look-ahead codes for enum parsing are
backported from 4.0.  This is required to avoid rejecting the
following code, which is valid:

  enum E { e };
  template <class T> enum E f(); // A function returning enum

The multiple-token look-ahead requirement is also a reason why
I choose to check for error in cp_parser_type_specifier
rather than the cp_parser_single_declaration suggested earlier
by Mark.

Tested on i686-pc-linux-gnu. OK for mainline and 3.4 branch?

--Kriang
2004-11-11  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/18123
	* parser.c (cp_parser_type_specifier): Don't create new enum
	type if it is not in the form 'enum [identifier] { [...] };'.
	Catch template declaration of enum. 
	(tsubst_decl) <TEMPLATE_DECL case>: Likewise.

2004-11-11  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/18123
	* g++.dg/parse/enum2.C: New test.


diff -cprN gcc-34-save/gcc/cp/parser.c gcc-34-new/gcc/cp/parser.c
*** gcc-34-save/gcc/cp/parser.c	Sat Aug 14 14:34:13 2004
--- gcc-34-new/gcc/cp/parser.c	Tue Nov  9 23:58:13 2004
*************** cp_parser_type_specifier (cp_parser* par
*** 8684,8704 ****
    keyword = token->keyword;
    switch (keyword)
      {
        /* Any of these indicate either a class-specifier, or an
  	 elaborated-type-specifier.  */
      case RID_CLASS:
      case RID_STRUCT:
      case RID_UNION:
-     case RID_ENUM:
        /* Parse tentatively so that we can back up if we don't find a
  	 class-specifier or enum-specifier.  */
        cp_parser_parse_tentatively (parser);
!       /* Look for the class-specifier or enum-specifier.  */
!       if (keyword == RID_ENUM)
! 	type_spec = cp_parser_enum_specifier (parser);
!       else
! 	type_spec = cp_parser_class_specifier (parser);
! 
        /* If that worked, we're done.  */
        if (cp_parser_parse_definitely (parser))
  	{
--- 8684,8723 ----
    keyword = token->keyword;
    switch (keyword)
      {
+     case RID_ENUM:
+       /* 'enum' [identifier] '{' introduces an enum-specifier;
+ 	 'enum' <anything else> introduces an elaborated-type-specifier.  */
+       if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_BRACE
+ 	  || (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
+ 	      && cp_lexer_peek_nth_token (parser->lexer, 3)->type
+ 	         == CPP_OPEN_BRACE))
+ 	{
+ 	  if (parser->num_template_parameter_lists)
+ 	    {
+ 	      error ("template declaration of `enum'");
+ 	      cp_parser_skip_to_end_of_block_or_statement (parser);
+ 	      type_spec = error_mark_node;
+ 	    }
+ 	  else
+ 	    type_spec = cp_parser_enum_specifier (parser);
+ 
+ 	  if (declares_class_or_enum)
+ 	    *declares_class_or_enum = 2;
+ 	  return type_spec;
+ 	}
+       else
+ 	goto elaborated_type_specifier;
+ 
        /* Any of these indicate either a class-specifier, or an
  	 elaborated-type-specifier.  */
      case RID_CLASS:
      case RID_STRUCT:
      case RID_UNION:
        /* Parse tentatively so that we can back up if we don't find a
  	 class-specifier or enum-specifier.  */
        cp_parser_parse_tentatively (parser);
!       /* Look for the class-specifier.  */
!       type_spec = cp_parser_class_specifier (parser);
        /* If that worked, we're done.  */
        if (cp_parser_parse_definitely (parser))
  	{
*************** cp_parser_type_specifier (cp_parser* par
*** 8710,8715 ****
--- 8729,8735 ----
        /* Fall through.  */
  
      case RID_TYPENAME:
+     elaborated_type_specifier:
        /* Look for an elaborated-type-specifier.  */
        type_spec = cp_parser_elaborated_type_specifier (parser,
  						       is_friend,
diff -cprN gcc-34-save/gcc/testsuite/g++.dg/parse/enum2.C gcc-34-new/gcc/testsuite/g++.dg/parse/enum2.C
*** gcc-34-save/gcc/testsuite/g++.dg/parse/enum2.C	Thu Jan  1 07:00:00 1970
--- gcc-34-new/gcc/testsuite/g++.dg/parse/enum2.C	Tue Nov  9 23:46:48 2004
***************
*** 0 ****
--- 1,7 ----
+ // { dg-do compile }
+ 
+ // Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+ 
+ // PR c++/18123: ICE pushing tag from invalid template.
+ 
+ template<int> enum E { e }; // { dg-error "template declaration" }
2004-11-11  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/18123
	* parser.c (cp_parser_type_specifier): Catch template declaration
	of enum.
	(tsubst_decl) <TEMPLATE_DECL case>: Likewise.

2004-11-11  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/18123
	* g++.dg/parse/enum2.C: New test.
	* g++.old-deja/g++.pt/enum5.C: Adjust error location.


diff -cprN gcc-main-save/gcc/cp/parser.c gcc-main-new/gcc/cp/parser.c
*** gcc-main-save/gcc/cp/parser.c	Sun Nov  7 22:40:15 2004
--- gcc-main-new/gcc/cp/parser.c	Tue Nov  9 23:06:06 2004
*************** cp_parser_type_specifier (cp_parser* par
*** 9114,9120 ****
  	      && cp_lexer_peek_nth_token (parser->lexer, 3)->type
  	         == CPP_OPEN_BRACE))
  	{
! 	  type_spec = cp_parser_enum_specifier (parser);
  	  if (declares_class_or_enum)
  	    *declares_class_or_enum = 2;
  	  if (decl_specs)
--- 9114,9128 ----
  	      && cp_lexer_peek_nth_token (parser->lexer, 3)->type
  	         == CPP_OPEN_BRACE))
  	{
! 	  if (parser->num_template_parameter_lists)
! 	    {
! 	      error ("template declaration of %qs", "enum");
! 	      cp_parser_skip_to_end_of_block_or_statement (parser);
! 	      type_spec = error_mark_node;
! 	    }
! 	  else
! 	    type_spec = cp_parser_enum_specifier (parser);
! 
  	  if (declares_class_or_enum)
  	    *declares_class_or_enum = 2;
  	  if (decl_specs)
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/parse/enum2.C gcc-main-new/gcc/testsuite/g++.dg/parse/enum2.C
*** gcc-main-save/gcc/testsuite/g++.dg/parse/enum2.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/parse/enum2.C	Tue Nov  9 23:45:13 2004
***************
*** 0 ****
--- 1,7 ----
+ // { dg-do compile }
+ 
+ // Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+ 
+ // PR c++/18123: ICE pushing tag from invalid template.
+ 
+ template<int> enum E { e }; // { dg-error "template declaration" }
diff -cprN gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/enum5.C gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/enum5.C
*** gcc-main-save/gcc/testsuite/g++.old-deja/g++.pt/enum5.C	Thu May  1 18:35:25 2003
--- gcc-main-new/gcc/testsuite/g++.old-deja/g++.pt/enum5.C	Wed Nov 10 20:44:18 2004
***************
*** 1,4 ****
  // { dg-do assemble  }
  
! template <>
! enum E {e}; // { dg-error "" } template declaration of enum
--- 1,4 ----
  // { dg-do assemble  }
  
! template <> // { dg-error "" } template declaration of enum
! enum E {e};

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