diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-02-13 23:30:43 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-02-13 23:30:43 +0100 |
commit | 5586014a397175dfbcc883e64b7c376e4cd6c3d1 (patch) | |
tree | 56624ad6c8c3f66c15331fc37d14bb94a8e52ccd | |
parent | 8d2eb30433ecedf4db7e00b62320973a587f4216 (diff) | |
download | gcc-5586014a397175dfbcc883e64b7c376e4cd6c3d1.zip gcc-5586014a397175dfbcc883e64b7c376e4cd6c3d1.tar.gz gcc-5586014a397175dfbcc883e64b7c376e4cd6c3d1.tar.bz2 |
re PR c++/35138 (g++ rejects valid code)
PR c++/35138
* parser.c (cp_parser_pseudo_destructor_name): If next tokens
are not identifier :: ~, return before calling cp_parser_type_name.
* g++.dg/template/member8.C: New test.
Co-Authored-By: Manuel López-Ibáñez <manu@gcc.gnu.org>
From-SVN: r132298
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/member8.C | 25 |
4 files changed, 51 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 38f9510..c237abd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2008-02-13 Jakub Jelinek <jakub@redhat.com> + Manuel Lopez-Ibanez <manu@gcc.gnu.org> + + PR c++/35138 + * parser.c (cp_parser_pseudo_destructor_name): If next tokens + are not identifier :: ~, return before calling cp_parser_type_name. + 2008-02-13 Jason Merrill <jason@redhat.com> PR c++/34962, c++/34937, c++/34939 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a648983..5f21574 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5164,24 +5164,26 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, additional qualification. */ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMPL)) { + /* At this point, we're looking for "type-name :: ~". The type-name + must not be a class-name, since this is a pseudo-destructor. So, + it must be either an enum-name, or a typedef-name -- both of which + are just identifiers. So, we peek ahead to check that the "::" + and "~" tokens are present; if they are not, then we can avoid + calling type_name. */ + if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME + || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE + || cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_COMPL) + { + cp_parser_error (parser, "non-scalar type"); + return; + } + /* Look for the type-name. */ *scope = TREE_TYPE (cp_parser_type_name (parser)); if (*scope == error_mark_node) return; - /* If we don't have ::~, then something has gone wrong. Since - the only caller of this function is looking for something - after `.' or `->' after a scalar type, most likely the - program is trying to get a member of a non-aggregate - type. */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE) - || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_COMPL) - { - cp_parser_error (parser, "request for member of non-aggregate type"); - return; - } - /* Look for the `::' token. */ cp_parser_require (parser, CPP_SCOPE, "`::'"); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3e660c9..0eac359 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-02-13 Jakub Jelinek <jakub@redhat.com> + + PR c++/35138 + * g++.dg/template/member8.C: New test. + 2008-02-13 Michael Matz <matz@suse.de> * gcc.dg/pr35065.c: Fix testcase warnings. diff --git a/gcc/testsuite/g++.dg/template/member8.C b/gcc/testsuite/g++.dg/template/member8.C new file mode 100644 index 0000000..074c655 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member8.C @@ -0,0 +1,25 @@ +// PR c++/35138 +// { dg-do compile } + +namespace N1 { struct A { }; } +namespace N2 { struct A { }; } +using namespace N1; +using namespace N2; + +template <typename T> int +foo (T const &t) +{ + return t.A; +} + +struct B +{ + int A; +}; + +int +main () +{ + B b; + foo (b); +} |