From be3b7dcf5c0f48ce72fe7a6f30db350e5c6872f3 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 29 Jun 2017 18:20:13 +0000 Subject: [PATCH] re PR c++/81247 (ICE on invalid C++ code with malformed namespace declaration: in do_push_nested_namespace, at cp/name-lookup.c:6002) PR c++/81247 * parser.c (cp_parser_namespace_definition): Immediately close the namespace if there's no open-brace. * name-lookup.c (do_pushdecl): Reset OLD when pushing into new namespace. From-SVN: r249804 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/name-lookup.c | 3 +++ gcc/cp/parser.c | 13 +++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/parse/pr81247-a.C | 13 +++++++++++++ gcc/testsuite/g++.dg/parse/pr81247-b.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/parse/pr81247-c.C | 13 +++++++++++++ 7 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/pr81247-a.C create mode 100644 gcc/testsuite/g++.dg/parse/pr81247-b.C create mode 100644 gcc/testsuite/g++.dg/parse/pr81247-c.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2c29f1e6d16..17da1c5868d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2017-06-29 Nathan Sidwell + + PR c++/81247 + * parser.c (cp_parser_namespace_definition): Immediately close the + namespace if there's no open-brace. + * name-lookup.c (do_pushdecl): Reset OLD when pushing into new + namespace. + 2017-06-29 Jason Merrill PR c++/81164 - ICE with invalid inherited constructor. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index f15c8116959..4beab850612 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2422,6 +2422,9 @@ do_pushdecl (tree decl, bool is_friend) { ns = current_namespace; slot = find_namespace_slot (ns, name, true); + /* Update OLD to reflect the namespace we're going to be + pushing into. */ + old = MAYBE_STAT_DECL (*slot); } old = update_binding (level, binding, slot, old, decl, is_friend); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 31840d6ea6f..375cd0a592d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18397,13 +18397,14 @@ cp_parser_namespace_definition (cp_parser* parser) warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace); /* Look for the `{' to validate starting the namespace. */ - cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); - - /* Parse the body of the namespace. */ - cp_parser_namespace_body (parser); + if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) + { + /* Parse the body of the namespace. */ + cp_parser_namespace_body (parser); - /* Look for the final `}'. */ - cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); + /* Look for the final `}'. */ + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); + } if (has_visibility) pop_visibility (1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49a84d64e55..d44f1a14862 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-06-29 Nathan Sidwell + + PR c++/81247 + * g++.dg/parse/pr81247-[abc].C: New. + 2017-06-29 Carl Love * gcc.target/powerpc/builtins-3-runnable.c (test_int_result, diff --git a/gcc/testsuite/g++.dg/parse/pr81247-a.C b/gcc/testsuite/g++.dg/parse/pr81247-a.C new file mode 100644 index 00000000000..c5b22ab479f --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr81247-a.C @@ -0,0 +1,13 @@ +// PR c++/81247 ICE + +namespace N // { dg-message "previous declaration" } +// { dg-error "expected" "" { target *-*-* } .+1 } +template < typename T > class A +{ // { dg-error "redeclared as different" } + template < T > friend class N; +}; + +void f () +{ + A < int > a1; // { dg-message "required from here" } +} diff --git a/gcc/testsuite/g++.dg/parse/pr81247-b.C b/gcc/testsuite/g++.dg/parse/pr81247-b.C new file mode 100644 index 00000000000..b2b035b9baf --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr81247-b.C @@ -0,0 +1,14 @@ +// PR c++/81247 confused error + +namespace N { // { dg-message "previous declaration" } +} + +template < typename T > class A +{ // { dg-error "redeclared as different" } + template < T > friend class N; +}; + +void f () +{ + A < int > a1; +} diff --git a/gcc/testsuite/g++.dg/parse/pr81247-c.C b/gcc/testsuite/g++.dg/parse/pr81247-c.C new file mode 100644 index 00000000000..32f41f28f41 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr81247-c.C @@ -0,0 +1,13 @@ +// PR c++/81247 confused error + +namespace N { // { dg-message "previous declaration" } + template < typename T > class A + { // { dg-error "conflicts with a previous" } + template < T > friend class N; + }; +} + +void f () +{ + N::A < int > a1; +} -- 2.30.2