From: Jakub Jelinek Date: Wed, 13 Feb 2008 22:30:43 +0000 (+0100) Subject: re PR c++/35138 (g++ rejects valid code) X-Git-Tag: releases/gcc-4.3.0~172 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5586014a397175dfbcc883e64b7c376e4cd6c3d1;p=thirdparty%2Fgcc.git 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 From-SVN: r132298 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 38f951032e6b..c237abda40de 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2008-02-13 Jakub Jelinek + Manuel Lopez-Ibanez + + 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 PR c++/34962, c++/34937, c++/34939 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a6489832d112..5f215742d49e 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 3e660c99b672..0eac359748fa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-02-13 Jakub Jelinek + + PR c++/35138 + * g++.dg/template/member8.C: New test. + 2008-02-13 Michael Matz * 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 000000000000..074c65543041 --- /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 int +foo (T const &t) +{ + return t.A; +} + +struct B +{ + int A; +}; + +int +main () +{ + B b; + foo (b); +}