On 11/21/18 8:46 PM, Marek Polacek wrote:
On Tue, Nov 20, 2018 at 04:59:46PM -0500, Jason Merrill wrote:
On 11/19/18 5:12 PM, Marek Polacek 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?

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);
+       }

This looks like we won't get any diagnostic in lower conformance modes if
there are multiple namespace scopes before the inline keyword.

If you mean something like
namespace A::B:C::inline D { }
then we do get a diagnostic.  nested-inline-ns1.C tests that.  Or do you
mean something else?

No, this is fine then.

         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;

This looks wrong: an inline namespace does not make its nested namespaces
inline as well.

A nested namespace definition cannot be inline.  This is supposed to handle
cases such as
namespace A::B::inline C { ... }
because after 'C' we don't see :: so it breaks and we call push_namespace
outside the for loop.

Ah, yes, I see. I was confused by the use of '|='; what is that for? Why not use '='? For that matter, why not modify is_inline in the loop instead of a new nested_inline_p variable?

Jason

Reply via email to