From patchwork Fri May 26 18:17:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 767507 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3wZDrC23jFz9s82 for ; Sat, 27 May 2017 04:17:31 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="OcV8GGsz"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=Sf1rA/xUnaiBuCeE9fuVG8rS7lcrr+H5bur4a0GCkQ7ZnvHr2K Ao6xWgawVI7/91BJ/9ymD19GdqTztl6xHBBKlGAzVSqnZ5jfFbUvO3AbJcanypvC XwoNUXRjtBz402HPTpZujM4+I8zgUlByaVH8tpwMyyeZ22rMBLT9Pg5Ow= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=PUoyK5wV99Lb2Kc1DBNdYRkAW8E=; b=OcV8GGsz0IuJFf5zAyrI Gn3W7aVgpp/htfcVqWDEYzh6LkyInkeArd86P8S9YZxjmLLsZAAilOg4AiFMUAJL drNfOEsfv/3hXwUgqcZw6JaLCcGRJG9o62BcxmKy/9PFq5Lnah4wPjKScb8Gpglq rTlEl3O/AKUyplHUYCU0L6w= Received: (qmail 79465 invoked by alias); 26 May 2017 18:17:14 -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 78304 invoked by uid 89); 26 May 2017 18:17:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=weed, Term, H*MI:8e0a, considers X-HELO: mail-yb0-f171.google.com Received: from mail-yb0-f171.google.com (HELO mail-yb0-f171.google.com) (209.85.213.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 26 May 2017 18:17:11 +0000 Received: by mail-yb0-f171.google.com with SMTP id p143so4133812yba.2 for ; Fri, 26 May 2017 11:17:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=e8ncM+Kfk6hPfxw25T3AxCfu6KGxW9H+jM3OcSCVyAU=; b=PIQThy5vj6AIEosAyuBqTzuq0avvEgG0OlT8bWzC+5Lx09R156/d8/Og4FMlRLPoHA MgkRPCUzXe6mW/YzevTAh+t76yFPKxH5UHOu5sf9UdJRv4tnZq5G/U+VORXOymLun8bB X6wMoj0Zh8Di6tgmaxgVQljA6L7vJImEvX6cwMvbMXB/kQ2sVHJTw6ZaD6p4Hw0yyvdo aUBoWQQXavpEylJynz6GjiO5my20iyYJh0avImY7stoBs7jDeg0ypPooxLtWv/yFf+8d Nl+QVScI9caLViDx+XlLNPxm9yxRcT8qlnGAbX9To3hT84fj1CPIHKiAGzzoFREZTZ63 rd4g== X-Gm-Message-State: AODbwcDe/SRwwH3cwIfhzGq7geO1RQN5q5LV6EMq3NpyKoMq51I2DWRR kcuyCoSi1slAbQ== X-Received: by 10.37.106.139 with SMTP id f133mr10280758ybc.172.1495822633660; Fri, 26 May 2017 11:17:13 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::2:a1d1]) by smtp.googlemail.com with ESMTPSA id m184sm612668ywd.1.2017.05.26.11.17.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 May 2017 11:17:13 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] Implement dr2061 Message-ID: <37ac92c6-8e0a-6ff1-9afe-888c1d574293@acm.org> Date: Fri, 26 May 2017 14:17:11 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.0 MIME-Version: 1.0 DR2061 concerns the meaning of: inline namespace One { namespace Term { } } namespace Term { } Does that second Term open a new namespace inside :: or reopen ::One::Term? DR2061 resolves to ::One::Term -- i.e. the lookup considers inline namespaces. This patch implements that behaviour. rather than a plain get_namespace_binding we do a lookup.search_qualified, but ignore any using directives. nathan 2017-05-26 Nathan Sidwell gcc/ Implement DR2061 * name-lookup.c (push_inline_namespaces): New. (push_namespace): Look inside inline namespaces. testsuite/ * g++.dg/cpp0x/dr2061.C: New. * g++.dg/parse/namespace-alias-1.C: Add more test. Index: cp/name-lookup.c =================================================================== --- cp/name-lookup.c (revision 248520) +++ cp/name-lookup.c (working copy) @@ -6057,6 +6057,23 @@ pushdecl_top_level_and_finish (tree x, t return x; } +/* Enter the namespaces from current_namerspace to NS. */ + +static int +push_inline_namespaces (tree ns) +{ + int count = 0; + if (ns != current_namespace) + { + gcc_assert (ns != global_namespace); + count += push_inline_namespaces (CP_DECL_CONTEXT (ns)); + resume_scope (NAMESPACE_LEVEL (ns)); + current_namespace = ns; + count++; + } + return count; +} + /* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we enter an anonymous namespace. If MAKE_INLINE is true, then we create an inline namespace (it is up to the caller to check upon @@ -6076,43 +6093,36 @@ push_namespace (tree name, bool make_inl if (!name) name = anon_identifier; - /* Check whether this is an extended namespace definition. */ - tree ns = get_namespace_binding (current_namespace, name); - if (ns && TREE_CODE (ns) == NAMESPACE_DECL) - { - if (tree dna = DECL_NAMESPACE_ALIAS (ns)) - { - /* We do some error recovery for, eg, the redeclaration of M - here: - - namespace N {} - namespace M = N; - namespace M {} - - However, in nasty cases like: - - namespace N - { - namespace M = N; - namespace M {} - } - - we just error out below, in duplicate_decls. */ - if (NAMESPACE_LEVEL (dna)->level_chain == current_binding_level) - { - error ("namespace alias %qD not allowed here, " - "assuming %qD", ns, dna); - ns = dna; - } - else - ns = NULL_TREE; - } - } - else - ns = NULL_TREE; + tree ns = NULL_TREE; + { + name_lookup lookup (name, 0); + if (!lookup.search_qualified (current_namespace, /*usings=*/false)) + ; + else if (TREE_CODE (lookup.value) != NAMESPACE_DECL) + ; + else if (tree dna = DECL_NAMESPACE_ALIAS (lookup.value)) + { + /* A namespace alias is not allowed here, but if the alias + is for a namespace also inside the current scope, + accept it with a diagnostic. That's better than dying + horribly. */ + if (is_nested_namespace (current_namespace, CP_DECL_CONTEXT (dna))) + { + error ("namespace alias %qD not allowed here, " + "assuming %qD", lookup.value, dna); + ns = dna; + } + } + else + ns = lookup.value; + } bool new_ns = false; - if (!ns) + if (ns) + /* DR2061. NS might be a member of an inline namespace. We + need to push into those namespaces. */ + count += push_inline_namespaces (CP_DECL_CONTEXT (ns)); + else { ns = build_lang_decl (NAMESPACE_DECL, name, void_type_node); SCOPE_DEPTH (ns) = SCOPE_DEPTH (current_namespace) + 1; Index: testsuite/g++.dg/cpp0x/dr2061.C =================================================================== --- testsuite/g++.dg/cpp0x/dr2061.C (revision 0) +++ testsuite/g++.dg/cpp0x/dr2061.C (working copy) @@ -0,0 +1,46 @@ +// { dg-do compile { target c++11 } } + +// DR2061, look inside inline namespace when pushing a namespace. + +inline namespace One +{ + namespace Term + { + } + inline namespace Two + { + namespace Space + { + } + } +} + +namespace Term +{ + void bob (); +} + +namespace Space +{ + void bill (); +} + +inline namespace Two +{ + void weed (); +} + +void One::Term::bob () {} +void One::Two::Space::bill () {} +void One::Two::weed () {} + +void Thing () +{ + Term::bob (); + Space::bill (); + weed (); +} + +// { dg-final { scan-assembler "_ZN3One4Term3bobEv:" } } +// { dg-final { scan-assembler "_ZN3One3Two5Space4billEv:" } } +// { dg-final { scan-assembler "_ZN3One3Two4weedEv:" } } Index: testsuite/g++.dg/parse/namespace-alias-1.C =================================================================== --- testsuite/g++.dg/parse/namespace-alias-1.C (revision 248520) +++ testsuite/g++.dg/parse/namespace-alias-1.C (working copy) @@ -5,3 +5,18 @@ namespace N namespace M = N; // { dg-message "previous declaration" } namespace M {} // { dg-error "declaration of namespace" } } + +namespace A +{ + namespace B + { + namespace C + { + } + } + + namespace D = B::C; + namespace D // { dg-error "not allowed" } + { + } +}