From 8a83a69363442100aa9435199e5d385716658255 Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Sun, 6 Jun 2004 02:08:18 +0000 Subject: [PATCH] re PR c++/15503 (nested template problem) PR c++/15503 * parser.c (cp_parser_mem_initializer_id): Gracefully reject 'typename', and accept 'template'. PR c++/15503 * g++.dg/template/meminit2.C: New test. From-SVN: r82660 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/parser.c | 12 +++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/meminit2.C | 21 +++++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/meminit2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 75aa42f91a8..8ec1302e035 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-06-06 Giovanni Bajo + + PR c++/15503 + * parser.c (cp_parser_mem_initializer_id): Gracefully reject + 'typename', and accept 'template'. + 2004-06-03 Andrew Pinski Jan Hubicka diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d7253f0a74b..0c94f7102db 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7383,8 +7383,16 @@ cp_parser_mem_initializer_id (cp_parser* parser) { bool global_scope_p; bool nested_name_specifier_p; + bool template_p = false; tree id; + /* `typename' is not allowed in this context ([temp.res]). */ + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME)) + { + error ("keyword `typename' not allowed in this context (a qualified " + "member initializer is implicitly a type)"); + cp_lexer_consume_token (parser->lexer); + } /* Look for the optional `::' operator. */ global_scope_p = (cp_parser_global_scope_opt (parser, @@ -7409,12 +7417,14 @@ cp_parser_mem_initializer_id (cp_parser* parser) /*type_p=*/true, /*is_declaration=*/true) != NULL_TREE); + if (nested_name_specifier_p) + template_p = cp_parser_optional_template_keyword (parser); /* If there is a `::' operator or a nested-name-specifier, then we are definitely looking for a class-name. */ if (global_scope_p || nested_name_specifier_p) return cp_parser_class_name (parser, /*typename_keyword_p=*/true, - /*template_keyword_p=*/false, + /*template_keyword_p=*/template_p, /*type_p=*/false, /*check_dependency_p=*/true, /*class_head_p=*/false, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d316dfc6151..197242d2bee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-06 Giovanni Bajo + + PR c++/15503 + * g++.dg/template/meminit2.C: New test. + 2004-06-04 Paolo Bonzini PR target/15822 diff --git a/gcc/testsuite/g++.dg/template/meminit2.C b/gcc/testsuite/g++.dg/template/meminit2.C new file mode 100644 index 00000000000..6abf2dfbba9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/meminit2.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// Origin: Mark Anders +// PR c++/15503: disambiguators in base classes and mem-initializers + +template struct O { + template struct I {}; +}; + +template +struct A : typename O::template I { // { dg-error "keyword `typename' not allowed" } + A() : typename O::template I() // { dg-error "keyword `typename' not allowed" } + {}; +}; + +template +struct B : O::template I { + B() : O::I() // { dg-error "used as template|it is a template" "" } + {}; +}; + +// { dg-bogus "end of input" "bogus token skipping in the parser" { xfail *-*-* } 17 } -- 2.30.2