This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH,committed] Fix type or template decision when parsingfunction parameter
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 20 Sep 2003 23:09:53 +0700 (ICT)
- Subject: [C++ PATCH,committed] Fix type or template decision when parsingfunction parameter
- Reply-to: <lerdsuwa at users dot sourceforge dot net>
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()
+ {
+ }