From ba0f36b0b01cb76cf8075bbe59bf69e4db3491ae Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sun, 3 Nov 2013 23:49:41 +0000 Subject: re PR c++/38313 (g++ fails to parse a member function with a parenthesized type name as its declarator) /cp 2013-11-03 Paolo Carlini PR c++/38313 * parser.c (cp_parser_constructor_declarator_p): Check that the class-name matches current_class_type. /testsuite 2013-11-03 Paolo Carlini PR c++/38313 * g++.dg/lookup/name-clash10.C: New. From-SVN: r204339 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/parser.c | 22 +++++++++++++++++----- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/lookup/name-clash10.C | 8 ++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/name-clash10.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cadf674..acdf4b5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-11-03 Paolo Carlini + + PR c++/38313 + * parser.c (cp_parser_constructor_declarator_p): Check that the + class-name matches current_class_type. + 2013-11-03 Marek Polacek * decl.c (cp_finish_decl): Move C++1y bounds checking... diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4e06e8a..3df746a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -22211,6 +22211,7 @@ static bool cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) { bool constructor_p; + bool outside_class_specifier_p; tree nested_name_specifier; cp_token *next_token; @@ -22243,11 +22244,14 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) /*check_dependency_p=*/false, /*type_p=*/false, /*is_declaration=*/false)); + + outside_class_specifier_p = (!at_class_scope_p () + || !TYPE_BEING_DEFINED (current_class_type) + || friend_p); + /* Outside of a class-specifier, there must be a nested-name-specifier. */ - if (!nested_name_specifier && - (!at_class_scope_p () || !TYPE_BEING_DEFINED (current_class_type) - || friend_p)) + if (!nested_name_specifier && outside_class_specifier_p) constructor_p = false; else if (nested_name_specifier == error_mark_node) constructor_p = false; @@ -22286,8 +22290,16 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) /*check_dependency_p=*/false, /*class_head_p=*/false, /*is_declaration=*/false); - /* If there was no class-name, then this is not a constructor. */ - constructor_p = !cp_parser_error_occurred (parser); + /* If there was no class-name, then this is not a constructor. + Otherwise, if we are in a class-specifier and we aren't + handling a friend declaration, check that its type matches + current_class_type (c++/38313). Note: error_mark_node + is left alone for error recovery purposes. */ + constructor_p = (!cp_parser_error_occurred (parser) + && (outside_class_specifier_p + || type_decl == error_mark_node + || same_type_p (current_class_type, + TREE_TYPE (type_decl)))); /* If we're still considering a constructor, we have to see a `(', to begin the parameter-declaration-clause, followed by either a diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c4358a9..09dc343 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-03 Paolo Carlini + + PR c++/38313 + * g++.dg/lookup/name-clash10.C: New. + 2013-11-03 Kugan Vivekanandarajah * gcc.target/arm/neon-vcond-gt.c: Scan for vbsl or vbit or vbif. diff --git a/gcc/testsuite/g++.dg/lookup/name-clash10.C b/gcc/testsuite/g++.dg/lookup/name-clash10.C new file mode 100644 index 0000000..0a089be --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/name-clash10.C @@ -0,0 +1,8 @@ +// PR c++/38313 + +struct foo { }; +struct bar { }; + +struct baz { + static foo (bar)(); +}; -- cgit v1.1