From patchwork Mon Nov 19 21:21:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1000104 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-490455-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="X3wtIvBX"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42zMGQ2H9Jz9s3x for ; Tue, 20 Nov 2018 08:21:34 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=TpQ7On5G4moEh5ierN8/xIW/m/lxxjnUVTbLXWtm2b4mvqsM67MOr Yi3TBfQ2hDm6VrvhhnCsQBaZgTQxrqR7YBMLUQlfH6wJEk2Dm/oaBJ4kMSrqJdSK BcR97okmgf+lAeX40A3SSaGb1qCzdmy0yJi92SPS2yKeDq5qHvOrn0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=XyefsQllpfH+QYY5Ub4XMKB3BLY=; b=X3wtIvBXq4J2ENpPdKJJ Xcs32e32eKzC+AGv6CnMbphzYiB3y4/DuDvNB8pIcS6fb8SQophYu8cGDZjpBWmy LopH3ctUUIhYhc/y5T+5LCtgSTh2j7aT2scedteGtuKOjmA6snez2SkYuJ5Zoz/s +BcilygE2lHiXBVdmSW1Hok= Received: (qmail 110650 invoked by alias); 19 Nov 2018 21:21:25 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 110628 invoked by uid 89); 19 Nov 2018 21:21:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 19 Nov 2018 21:21:23 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E1E94309706E for ; Mon, 19 Nov 2018 21:21:21 +0000 (UTC) Received: from redhat.com (unknown [10.20.4.212]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6F3D9600D7; Mon, 19 Nov 2018 21:21:21 +0000 (UTC) Date: Mon, 19 Nov 2018 16:21:19 -0500 From: Marek Polacek To: Jason Merrill , GCC Patches Subject: C++ PATCH to implement P1094R2, Nested inline namespaces Message-ID: <20181119212119.GX28582@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) This patch implements another C++20 feature, nested inline namespaces. This was fairly simple, one just has to be careful not to blithely consume the inline keyword, making a non-valid program valid. Another minor gotcha was to handle the innermost 'inline' correctly. Note that inline namespace A::B { ... } continues to be invalid. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-11-19 Marek Polacek 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. * g++.dg/cpp2a/nested-inline-ns3.C: New test. diff --git gcc/cp/parser.c gcc/cp/parser.c index 88fc426102b..8b8304acca7 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -18864,6 +18864,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) { @@ -18882,6 +18883,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); @@ -18896,7 +18908,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, @@ -18905,7 +18922,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"); @@ -18918,7 +18937,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"); @@ -18927,7 +18946,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..95b4d3378d1 --- /dev/null +++ gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C @@ -0,0 +1,26 @@ +// P1094R2 +// { dg-do compile { target c++2a } } + +namespace A::inline B::C { + int i; +} + +namespace D::E::inline F { + 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; +} diff --git gcc/testsuite/g++.dg/cpp2a/nested-inline-ns3.C gcc/testsuite/g++.dg/cpp2a/nested-inline-ns3.C new file mode 100644 index 00000000000..8b81c1383db --- /dev/null +++ gcc/testsuite/g++.dg/cpp2a/nested-inline-ns3.C @@ -0,0 +1,11 @@ +// P1094R2 +// { dg-do compile { target c++17 } } +// { dg-options "-Wpedantic" } + +namespace A::inline B::C { // { dg-warning "nested inline namespace definitions only" "" { target c++17_down } } + int i; +} + +namespace D::E::inline F { // { dg-warning "nested inline namespace definitions only" "" { target c++17_down } } + int i; +}