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