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,committed] Fix type or template decision when parsingfunction parameter


Hi

We currently accepts code like

  template <class T> class A {};
  template <class U> void f(A &) {}

in the parser.  We forget to notice that the template header
'template <class U>' belongs to the function 'f', not for the
function parameter 'class A'.  This is fixed by the patch below.
The patch also fixes the ICE in PR157 (although this exposes
duplicate error message problem that will be dealt with later.)

Tested on i686-pc-linux-gnu.  Committed to main trunk as obvious.

--Kriang


2003-09-20  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/157
	* parser.c (cp_parser_direct_declarator): Clear
	parser->num_template_parameter_lists when parsing function
	parameters.
	(cp_parser_constructor_declarator_p): Likewise.

2003-09-20  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/157
	* g++.dg/parse/crash12.C: New test.



diff -cprN gcc-main-save/gcc/cp/parser.c gcc-main-new/gcc/cp/parser.c
*** gcc-main-save/gcc/cp/parser.c	Mon Sep 15 21:18:15 2003
--- gcc-main-new/gcc/cp/parser.c	Sat Sep 20 19:55:53 2003
*************** cp_parser_direct_declarator (cp_parser* 
*** 9720,9725 ****
--- 9720,9726 ----
  	  if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
  	    {
  	      tree params;
+ 	      unsigned saved_num_template_parameter_lists;
  	      
  	      cp_parser_parse_tentatively (parser);
  
*************** cp_parser_direct_declarator (cp_parser* 
*** 9733,9741 ****
--- 9734,9751 ----
  		  parser->in_declarator_p = true;
  		}
  	  
+ 	      /* Inside the function parameter list, surrounding
+ 		 template-parameter-lists do not apply.  */
+ 	      saved_num_template_parameter_lists
+ 		= parser->num_template_parameter_lists;
+ 	      parser->num_template_parameter_lists = 0;
+ 
  	      /* Parse the parameter-declaration-clause.  */
  	      params = cp_parser_parameter_declaration_clause (parser);
  
+ 	      parser->num_template_parameter_lists
+ 		= saved_num_template_parameter_lists;
+ 
  	      /* If all went well, parse the cv-qualifier-seq and the
  	     	 exception-specification.  */
  	      if (cp_parser_parse_definitely (parser))
*************** cp_parser_constructor_declarator_p (cp_p
*** 13436,13441 ****
--- 13446,13452 ----
  	  && !cp_parser_storage_class_specifier_opt (parser))
  	{
  	  tree type;
+ 	  unsigned saved_num_template_parameter_lists;
  
  	  /* Names appearing in the type-specifier should be looked up
  	     in the scope of the class.  */
*************** cp_parser_constructor_declarator_p (cp_p
*** 13456,13461 ****
--- 13467,13479 ----
  		}
  	      push_scope (type);
  	    }
+ 
+ 	  /* Inside the constructor parameter list, surrounding
+ 	     template-parameter-lists do not apply.  */
+ 	  saved_num_template_parameter_lists
+ 	    = parser->num_template_parameter_lists;
+ 	  parser->num_template_parameter_lists = 0;
+ 
  	  /* Look for the type-specifier.  */
  	  cp_parser_type_specifier (parser,
  				    CP_PARSER_FLAGS_NONE,
*************** cp_parser_constructor_declarator_p (cp_p
*** 13463,13468 ****
--- 13481,13490 ----
  				    /*is_declarator=*/true,
  				    /*declares_class_or_enum=*/NULL,
  				    /*is_cv_qualifier=*/NULL);
+ 
+ 	  parser->num_template_parameter_lists
+ 	    = saved_num_template_parameter_lists;
+ 
  	  /* Leave the scope of the class.  */
  	  if (type)
  	    pop_scope (type);
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/parse/crash12.C gcc-main-new/gcc/testsuite/g++.dg/parse/crash12.C
*** gcc-main-save/gcc/testsuite/g++.dg/parse/crash12.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/parse/crash12.C	Sat Sep 20 20:09:12 2003
***************
*** 0 ****
--- 1,24 ----
+ // { dg-do compile }
+ 
+ // Origin: Martin von Loewis <martin@v.loewis.de>
+ 
+ // PR c++/157: Incorrect type/template decision in function parameter.
+ 
+ template <class _Tp> class auto_ptr {};
+ template <class _Tp>
+ class counted_ptr
+ {
+ public:
+   counted_ptr(auto_ptr<_Tp>& __a);		// { dg-error "candidate" }
+   auto_ptr<_Tp> auto_ptr();
+ };
+ 
+ template <class _Tp>
+ inline counted_ptr<_Tp>::counted_ptr(class auto_ptr& __a) // { dg-error "required" }
+ {						// { dg-error "no type|not match|template" }
+ }
+ 
+ template <class _Tp>
+ inline class auto_ptr<_Tp> counted_ptr<_Tp>::auto_ptr() 
+ {
+ }


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