On Tue, Nov 20, 2018 at 04:59:46PM -0500, Jason Merrill wrote:
> On 11/19/18 5:12 PM, Marek Polacek wrote:
>> > +  /* 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.  So I still don't see a bug; do you have a test that
>I got wrong?

The way I read the question is "what does

namespace A::inline B::C::D {...}

do?".

C and D are not inline. For what it's worth, I had an earlier very incomplete
stab at it, haven't looked how complete it really was; I know that it didn't
handle diagnostics as well as yours, and I have no recollection
of whether it handles the cases like the above. See attached.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 82b8ef8..cc5427a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12729,6 +12729,7 @@ cp_parser_declaration (cp_parser* parser)
                || (token2.type == CPP_OPEN_SQUARE
                    && cp_lexer_peek_nth_token (parser->lexer, 3)->type
                    == CPP_OPEN_SQUARE)
+	       || token2.keyword == RID_INLINE
 	       /* An unnamed namespace definition.  */
 	       || token2.type == CPP_OPEN_BRACE
 	       || token2.keyword == RID_ATTRIBUTE))
@@ -18533,10 +18534,24 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Parse any specified attributes before the identifier.  */
   tree attribs = cp_parser_attributes_opt (parser);
 
+  bool is_maybe_nested_inline = is_inline;
+
   for (;;)
     {
       identifier = NULL_TREE;
       
+      if (cxx_dialect > cxx17)
+	{
+	  is_maybe_nested_inline =
+	    cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE);
+
+	  if (is_maybe_nested_inline)
+	    {
+	      maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES);
+	      cp_lexer_consume_token (parser->lexer);
+	    }
+	}
+
       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
 	{
 	  identifier = cp_parser_identifier (parser);
@@ -18555,7 +18570,8 @@ 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, is_maybe_nested_inline) : 0)
 	nested_definition_count += count;
       else
 	cp_parser_error (parser, "nested namespace name required");
@@ -18573,7 +18589,8 @@ cp_parser_namespace_definition (cp_parser* parser)
 	      "a nested namespace definition cannot be inline");
 
   /* Start the namespace.  */
-  nested_definition_count += push_namespace (identifier, is_inline);
+  nested_definition_count +=
+    push_namespace (identifier, is_maybe_nested_inline);
 
   bool has_visibility = handle_namespace_attrs (current_namespace, attribs);
 

Reply via email to