On Mon, Nov 19, 2018 at 11:12 PM Marek Polacek <pola...@redhat.com> wrote: > > On Mon, Nov 19, 2018 at 10:33:17PM +0100, Jakub Jelinek wrote: > > On Mon, Nov 19, 2018 at 04:21:19PM -0500, Marek Polacek wrote: > > > 2018-11-19 Marek Polacek <pola...@redhat.com> > > > > > > Implement P1094R2, Nested inline namespaces. > > > * g++.dg/cpp2a/nested-inline-ns1.C: New test. > > > * g++.dg/cpp2a/nested-inline-ns2.C: New test. > > > * g++.dg/cpp2a/nested-inline-ns3.C: New test. > > > > Just a small testsuite comment. > > > > > --- /dev/null > > > +++ gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C > > > @@ -0,0 +1,26 @@ > > > +// P1094R2 > > > +// { dg-do compile { target c++2a } } > > > > Especially because 2a testing isn't included by default, but also > > to make sure it works right even with -std=c++17, wouldn't it be better to > > drop the nested-inline-ns3.C test, make this test c++17 or > > even better always enabled, add dg-options "-Wpedantic" and > > just add dg-warning with c++17_down and c++14_down what should be > > warned on the 3 lines (with .-1 for c++14_down)? > > > > Or if you want add some further testcases that will test how > > c++17 etc. will dg-error on those with -pedantic-errors etc. > > Sure, I've made it { target c++11 } and dropped the third test: > > Bootstrapped/regtested on x86_64-linux, ok for trunk?
Just another small comment - given the usual high number of C++ regressions delaying the release is Stage3 the right time to add new language features? > 2018-11-19 Marek Polacek <pola...@redhat.com> > > Implement P1094R2, Nested inline namespaces. > * parser.c (cp_parser_namespace_definition): Parse the optional inline > keyword in a nested-namespace-definition. Adjust push_namespace call. > Formatting fix. > > * g++.dg/cpp2a/nested-inline-ns1.C: New test. > * g++.dg/cpp2a/nested-inline-ns2.C: New test. > > diff --git gcc/cp/parser.c gcc/cp/parser.c > index 292cce15676..f39e9d753d2 100644 > --- gcc/cp/parser.c > +++ gcc/cp/parser.c > @@ -18872,6 +18872,7 @@ cp_parser_namespace_definition (cp_parser* parser) > cp_ensure_no_oacc_routine (parser); > > bool is_inline = cp_lexer_next_token_is_keyword (parser->lexer, > RID_INLINE); > + const bool topmost_inline_p = is_inline; > > if (is_inline) > { > @@ -18890,6 +18891,17 @@ cp_parser_namespace_definition (cp_parser* parser) > { > identifier = NULL_TREE; > > + bool nested_inline_p = cp_lexer_next_token_is_keyword (parser->lexer, > + RID_INLINE); > + if (nested_inline_p && nested_definition_count != 0) > + { > + if (cxx_dialect < cxx2a) > + pedwarn (cp_lexer_peek_token (parser->lexer)->location, > + OPT_Wpedantic, "nested inline namespace definitions only > " > + "available with -std=c++2a or -std=gnu++2a"); > + cp_lexer_consume_token (parser->lexer); > + } > + > if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) > { > identifier = cp_parser_identifier (parser); > @@ -18904,7 +18916,12 @@ cp_parser_namespace_definition (cp_parser* parser) > } > > if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE)) > - break; > + { > + /* Don't forget that the innermost namespace might have been > + marked as inline. */ > + is_inline |= nested_inline_p; > + break; > + } > > if (!nested_definition_count && cxx_dialect < cxx17) > pedwarn (input_location, OPT_Wpedantic, > @@ -18913,7 +18930,9 @@ cp_parser_namespace_definition (cp_parser* parser) > > /* Nested namespace names can create new namespaces (unlike > other qualified-ids). */ > - if (int count = identifier ? push_namespace (identifier) : 0) > + if (int count = (identifier > + ? push_namespace (identifier, nested_inline_p) > + : 0)) > nested_definition_count += count; > else > cp_parser_error (parser, "nested namespace name required"); > @@ -18926,7 +18945,7 @@ cp_parser_namespace_definition (cp_parser* parser) > if (nested_definition_count && attribs) > error_at (token->location, > "a nested namespace definition cannot have attributes"); > - if (nested_definition_count && is_inline) > + if (nested_definition_count && topmost_inline_p) > error_at (token->location, > "a nested namespace definition cannot be inline"); > > @@ -18935,7 +18954,7 @@ cp_parser_namespace_definition (cp_parser* parser) > > bool has_visibility = handle_namespace_attrs (current_namespace, attribs); > > - warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace); > + warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace); > > /* Look for the `{' to validate starting the namespace. */ > matching_braces braces; > diff --git gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C > gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C > new file mode 100644 > index 00000000000..8c9573ea5db > --- /dev/null > +++ gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C > @@ -0,0 +1,29 @@ > +// P1094R2 > +// { dg-do compile { target c++11 } } > +// { dg-options "-Wpedantic" } > + > +namespace A::inline B::C { // { dg-warning "nested inline namespace > definitions only" "" { target c++17_down } } > +// { dg-warning "nested namespace definitions only available" "" { target > c++14_down } .-1 } > + int i; > +} > + > +namespace D::E::inline F { // { dg-warning "nested inline namespace > definitions only" "" { target c++17_down } } > +// { dg-warning "nested namespace definitions only available" "" { target > c++14_down } .-1 } > + int j; > +} > + > +inline namespace X { > + int x; > +} > + > +// Make sure the namespaces are marked inline. > +void > +g () > +{ > + A::B::C::i++; > + A::C::i++; > + D::E::j++; > + D::E::F::j++; > + X::x++; > + x++; > +} > diff --git gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C > gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C > new file mode 100644 > index 00000000000..9b5f2cab47b > --- /dev/null > +++ gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C > @@ -0,0 +1,26 @@ > +// P1094R2 > +// { dg-do compile { target c++2a } } > + > +inline namespace A::B { // { dg-error "a nested namespace definition cannot > be inline" } > + int i; > +} > + > +namespace inline C::D { // { dg-error "expected|does not name a type" } > + int i; > +} > + > +namespace E::F inline { // { dg-error "expected" } > + int i; > +} > + > +namespace inline G { // { dg-error "expected|does not name a type" } > + int i; > +} > + > +inline namespace inline H { // { dg-error "expected|does not name a type" } > + int i; > +} > + > +inline namespace inline I::J { // { dg-error "expected|does not name a type" > } > + int i; > +}