diff options
author | Jason Merrill <jason@redhat.com> | 2009-01-19 17:50:43 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-01-19 17:50:43 -0500 |
commit | 051342116322b25db0ef6c38838a76c7a0c1231a (patch) | |
tree | f5ff955481a4d4f4585623f8173ca24598645feb /gcc | |
parent | 9295d9eda367410dec7f531b76fb8b120ffd6375 (diff) | |
download | gcc-051342116322b25db0ef6c38838a76c7a0c1231a.zip gcc-051342116322b25db0ef6c38838a76c7a0c1231a.tar.gz gcc-051342116322b25db0ef6c38838a76c7a0c1231a.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/dtor5.C | 21 |
5 files changed, 60 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a58d4ac..5808ee5f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-01-19 Jason Merrill <jason@redhat.com> + + 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 <jason@redhat.com> PR c++/38877 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 526a9a3..5baf5f5 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 415b8a2..6c69256 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 bbe8975..e9bfcd2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-19 Jason Merrill <jason@redhat.com> + + PR c++/23287 + * g++.dg/template/dtor5.C: New test. + 2009-01-19 Mikael Morin <mikael.morin@tele2.fr> 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 0000000..8fa4eeb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor5.C @@ -0,0 +1,21 @@ +// PR c++/23287 + +template <class T> struct A +{ + int i; + ~A(); +}; + +template <class T> void f(A<T> *ap) { + ap->~A(); +} + +template <class T> void g(A<T> *ap) { + ap->~B(); // { dg-error "destructor name" } +} + +int main() +{ + f(new A<int>); + g(new A<int>); +} |