From 051342116322b25db0ef6c38838a76c7a0c1231a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 19 Jan 2009 17:50:43 -0500 Subject: [PATCH] re PR c++/23287 (Explicitly invoking destructor of template class in a template and is dependent) PR c++/23287 * parser.c (cp_parser_unqualified_id): In a template, accept ~identifier. * typeck.c (lookup_destructor): Handle IDENTIFIER_NODE. From-SVN: r143502 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/parser.c | 10 ++++++++++ gcc/cp/typeck.c | 20 +++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/dtor5.C | 21 +++++++++++++++++++++ 5 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/dtor5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a58d4ac27d5..5808ee5f7d8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-01-19 Jason Merrill + + PR c++/23287 + * parser.c (cp_parser_unqualified_id): In a template, + accept ~identifier. + * typeck.c (lookup_destructor): Handle IDENTIFIER_NODE. + 2009-01-16 Jason Merrill PR c++/38877 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 526a9a3acef..5baf5f55196 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3880,6 +3880,8 @@ cp_parser_unqualified_id (cp_parser* parser, parser->scope = NULL_TREE; parser->object_scope = NULL_TREE; parser->qualifying_scope = NULL_TREE; + if (processing_template_decl) + cp_parser_parse_tentatively (parser); type_decl = cp_parser_class_name (parser, /*typename_keyword_p=*/false, @@ -3888,6 +3890,14 @@ cp_parser_unqualified_id (cp_parser* parser, /*check_dependency=*/false, /*class_head_p=*/false, declarator_p); + if (processing_template_decl + && ! cp_parser_parse_definitely (parser)) + { + /* We couldn't find a type with this name, so just accept + it and check for a match at instantiation time. */ + type_decl = cp_parser_identifier (parser); + return build_nt (BIT_NOT_EXPR, type_decl); + } } /* If an error occurred, assume that the name of the destructor is the same as the name of the qualifying diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 415b8a26291..6c69256aa39 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2101,8 +2101,8 @@ build_class_member_access_expr (tree object, tree member, return result; } -/* Return the destructor denoted by OBJECT.SCOPE::~DTOR_NAME, or, if - SCOPE is NULL, by OBJECT.~DTOR_NAME. */ +/* Return the destructor denoted by OBJECT.SCOPE::DTOR_NAME, or, if + SCOPE is NULL, by OBJECT.DTOR_NAME, where DTOR_NAME is ~type. */ static tree lookup_destructor (tree object, tree scope, tree dtor_name) @@ -2117,7 +2117,21 @@ lookup_destructor (tree object, tree scope, tree dtor_name) scope, dtor_type); return error_mark_node; } - if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type))) + if (TREE_CODE (dtor_type) == IDENTIFIER_NODE) + { + /* In a template, names we can't find a match for are still accepted + destructor names, and we check them here. */ + if (check_dtor_name (object_type, dtor_type)) + dtor_type = object_type; + else + { + error ("object type %qT does not match destructor name ~%qT", + object_type, dtor_type); + return error_mark_node; + } + + } + else if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type))) { error ("the type being destroyed is %qT, but the destructor refers to %qT", TYPE_MAIN_VARIANT (object_type), dtor_type); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bbe897580dd..e9bfcd25dea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-19 Jason Merrill + + PR c++/23287 + * g++.dg/template/dtor5.C: New test. + 2009-01-19 Mikael Morin PR fortran/38859 diff --git a/gcc/testsuite/g++.dg/template/dtor5.C b/gcc/testsuite/g++.dg/template/dtor5.C new file mode 100644 index 00000000000..8fa4eeb6f06 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor5.C @@ -0,0 +1,21 @@ +// PR c++/23287 + +template struct A +{ + int i; + ~A(); +}; + +template void f(A *ap) { + ap->~A(); +} + +template void g(A *ap) { + ap->~B(); // { dg-error "destructor name" } +} + +int main() +{ + f(new A); + g(new A); +} -- 2.30.2