diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3c93c355f1a..0d990506d02 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2006-05-17 Mark Mitchell + PR c++/26122 + * decl2.c (check_member_template): Remove checks for virtual + functions. + * parser.c (cp_parser_function_specifier_opt): Complain about + virtual templates. + (cp_parser_pure_specifier): Likewise. + PR c++/26068 * parser.c (cp_parser_set_storage_class): Check for invalid uses of storage classes on unbraced linkage diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index f75c4ab602a..27b88f06b52 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -452,16 +452,9 @@ check_member_template (tree tmpl) error ("invalid declaration of member template %q#D in local class", decl); - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl)) - { - /* 14.5.2.3 [temp.mem] - - A member function template shall not be virtual. */ - error - ("invalid use of % in template declaration of %q#D", - decl); - DECL_VIRTUAL_P (decl) = 0; - } + /* The parser rejects any use of virtual in a function template. */ + gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL + && DECL_VIRTUAL_P (decl))); /* The debug-information generating code doesn't know what to do with member templates. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c6124835599..e80b8ee09d9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7664,7 +7664,12 @@ cp_parser_function_specifier_opt (cp_parser* parser, break; case RID_VIRTUAL: - if (decl_specs) + /* 14.5.2.3 [temp.mem] + + A member function template shall not be virtual. */ + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + error ("templates may not be %"); + else if (decl_specs) ++decl_specs->specs[(int) ds_virtual]; break; @@ -13864,12 +13869,20 @@ cp_parser_pure_specifier (cp_parser* parser) /* Look for the `0' token. */ token = cp_lexer_consume_token (parser->lexer); /* c_lex_with_flags marks a single digit '0' with PURE_ZERO. */ - if (token->type == CPP_NUMBER && (token->flags & PURE_ZERO)) - return integer_zero_node; + if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO)) + { + cp_parser_error (parser, + "invalid pure specifier (only `= 0' is allowed)"); + cp_parser_skip_to_end_of_statement (parser); + return error_mark_node; + } + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + { + error ("templates may not be %"); + return error_mark_node; + } - cp_parser_error (parser, "invalid pure specifier (only `= 0' is allowed)"); - cp_parser_skip_to_end_of_statement (parser); - return error_mark_node; + return integer_zero_node; } /* Parse a constant-initializer. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5f5dca0355..9cf94049cf8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2006-05-17 Mark Mitchell + PR c++/26122 + * g++.old-deja/g++.oliva/template9.C: Remove XFAIL. + PR c++/26068 * g++.dg/opt/pr17697-3.C: Remove invalid extern specifier. * g++.dg/parse/linkage1.C: New test. diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/template9.C b/gcc/testsuite/g++.old-deja/g++.oliva/template9.C index c237dbc5848..02be37a5f99 100644 --- a/gcc/testsuite/g++.old-deja/g++.oliva/template9.C +++ b/gcc/testsuite/g++.old-deja/g++.oliva/template9.C @@ -7,5 +7,5 @@ struct foo { template - void bar() = 0; // { dg-error "" "" { xfail *-*-* } } invalid initializer - + void bar() = 0; // { dg-error "virtual" } };