From c0dc47a866978c70a9c008882850dfdf059fd52d Mon Sep 17 00:00:00 2001 From: Volker Reichelt Date: Thu, 3 Aug 2006 02:49:07 +0000 Subject: [PATCH] re PR c++/27508 (ICE on invalid destructor name) PR c++/27508 * parser.c (cp_parser_unqualified_id): Check for invalid scopes when parsing destructor names. * g++.dg/parse/dtor9.C: New test. * g++.dg/parse/dtor10.C: New test. * g++.dg/other/error7.C: Adjust error-marker. From-SVN: r115896 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/parser.c | 19 +++++++++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/other/error7.C | 2 +- gcc/testsuite/g++.dg/parse/dtor10.C | 9 +++++++++ gcc/testsuite/g++.dg/parse/dtor9.C | 5 +++++ 6 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/dtor10.C create mode 100644 gcc/testsuite/g++.dg/parse/dtor9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 93d4d23..47513ef 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2006-08-03 Volker Reichelt + PR c++/27508 + * parser.c (cp_parser_unqualified_id): Check for invalid scopes + when parsing destructor names. + PR c++/28274 * decl.c (duplicate_decls): Call check_default_args here. (start_preparsed_function): Do not call check_default_args. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c422401..aa29787 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3416,9 +3416,24 @@ cp_parser_unqualified_id (cp_parser* parser, object_scope = parser->object_scope; qualifying_scope = parser->qualifying_scope; + /* Check for invalid scopes. */ + if (scope == error_mark_node) + { + cp_parser_skip_to_end_of_statement (parser); + return error_mark_node; + } + if (scope && TREE_CODE (scope) == NAMESPACE_DECL) + { + if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) + error ("scope %qT before %<~%> is not a class-name", scope); + cp_parser_skip_to_end_of_statement (parser); + return error_mark_node; + } + gcc_assert (!scope || TYPE_P (scope)); + /* If the name is of the form "X::~X" it's OK. */ token = cp_lexer_peek_token (parser->lexer); - if (scope && TYPE_P (scope) + if (scope && token->type == CPP_NAME && (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_PAREN) @@ -3500,7 +3515,7 @@ cp_parser_unqualified_id (cp_parser* parser, destructor is the same as the name of the qualifying class. That allows us to keep parsing after running into ill-formed destructor names. */ - if (type_decl == error_mark_node && scope && TYPE_P (scope)) + if (type_decl == error_mark_node && scope) return build_nt (BIT_NOT_EXPR, scope); else if (type_decl == error_mark_node) return error_mark_node; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8f17cab..dfe0f98 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2006-08-03 Volker Reichelt + PR c++/27508 + * g++.dg/parse/dtor9.C: New test. + * g++.dg/parse/dtor10.C: New test. + * g++.dg/other/error7.C: Adjust error-marker. + PR c++/28274 * g++.dg/other/default5.C: New test. diff --git a/gcc/testsuite/g++.dg/other/error7.C b/gcc/testsuite/g++.dg/other/error7.C index eadb7b5..9845b41 100644 --- a/gcc/testsuite/g++.dg/other/error7.C +++ b/gcc/testsuite/g++.dg/other/error7.C @@ -8,5 +8,5 @@ namespace N {} void foo(void) { - N::~A(); // { dg-error "not a member" } + N::~A(); // { dg-error "not a class-name" } } diff --git a/gcc/testsuite/g++.dg/parse/dtor10.C b/gcc/testsuite/g++.dg/parse/dtor10.C new file mode 100644 index 0000000..a6e9054 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/dtor10.C @@ -0,0 +1,9 @@ +// PR c++/27508 +// { dg-do compile } + +namespace N +{ + struct A { ~A(); }; +} + +N::~A () {} // { dg-error "not a class-name" } diff --git a/gcc/testsuite/g++.dg/parse/dtor9.C b/gcc/testsuite/g++.dg/parse/dtor9.C new file mode 100644 index 0000000..64c82ce --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/dtor9.C @@ -0,0 +1,5 @@ +// PR c++/27508 +// { dg-do compile } + +struct A; +using ::~A; // { dg-error "not a class-name" } -- 2.7.4