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