From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11413 invoked by alias); 16 May 2017 11:35:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 11386 invoked by uid 89); 16 May 2017 11:35:58 -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=nest X-HELO: mail-yw0-f173.google.com Received: from mail-yw0-f173.google.com (HELO mail-yw0-f173.google.com) (209.85.161.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 May 2017 11:35:56 +0000 Received: by mail-yw0-f173.google.com with SMTP id 203so51132828ywe.0 for ; Tue, 16 May 2017 04:35:59 -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=72lqAQjY6yB8hYS7rPq2rg5i13RlTULG0hFtI4yExBU=; b=CEMf8uCllh2G+thmRGUG0L7Q9GdeM9pYQDHzdKICXZRGJxMPVI1QLOyNlDzEQEkjwy TdtOkdylTVyM1UfQdt2mg69/FKI1ieQl3IzJIs1s9j2PUspEqBKPt4O6cGefYWR8nBQm y68xOKIrQeGzGd4rWRue+tl8UwGYTDscQpaupTUPCyG+wCeTFNUwfHpCSi+Ry90f6Cru pVKW5R/aR6S8w10ViloFjvt16gFH2EO9EGspEtuCl1FmcI+H6OqjoCASuvHn2d3xsXmM NSnr+9GzecSeHqq6TMwAd1dN1VOeeYRc7xdTQUXUIHGi7Rlb8RKgqFV055MyDDxH2cWR zoDg== X-Gm-Message-State: AODbwcCqDllTCv0YM2DiCSQcZDcvIClem94huVZ+YU08mKlGWJyUm7uC tEkUhfkwsYn6bw== X-Received: by 10.13.200.69 with SMTP id k66mr2626450ywd.198.1494934558319; Tue, 16 May 2017 04:35:58 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::7:4a1a]) by smtp.googlemail.com with ESMTPSA id k133sm6477294ywe.64.2017.05.16.04.35.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 May 2017 04:35:57 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] namespace depth Message-ID: <5dfc596d-edbf-3ea1-0c56-8446975f20e1@acm.org> Date: Tue, 16 May 2017 11:41:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------0A4E07B54A8F8884DD3840C0" X-SW-Source: 2017-05/txt/msg01264.txt.bz2 This is a multi-part message in MIME format. --------------0A4E07B54A8F8884DD3840C0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 431 Currently, namespace_decls have no record of how deep they reside in the namespace tree. That makes is_ancestor overly complex (and therefore bleeds over into unqualified namespace lookup) This patch adds a SCOPE_DEPTH macro (it may be useful to extend to other scope-like things). It uses the base.u.bits.address_space field, which is available to us. We 'only' permit 255 levels of namespace. nathan -- Nathan Sidwell --------------0A4E07B54A8F8884DD3840C0 Content-Type: text/x-patch; name="dpth.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="dpth.diff" Content-length: 5894 2017-05-16 Nathan Sidwell * cp-tree.h (SCOPE_DEPTH): New. * name-lookup.h (is_nested_namespace): Declare. * name-lookup.c (is_nested_namespace): New. (is_ancestor): Use it. (set_decl_namespace): Likewise. (push_namespace): Set SCOPE_DEPTH. * pt.c (check_specialization_namespace): Use is_nested_namespace. (check_unqualigied_spec_or_inst): Likewise. Index: cp-tree.h =================================================================== --- cp-tree.h (revision 248094) +++ cp-tree.h (working copy) @@ -2917,6 +2917,11 @@ struct GTY(()) lang_decl { #define LOCAL_CLASS_P(NODE) \ (decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE) +/* The nesting depth of namespace, class or function. Makes is_ancestor much + simpler. Only 8 bits available. */ +#define SCOPE_DEPTH(NODE) \ + (NAMESPACE_DECL_CHECK (NODE)->base.u.bits.address_space) + /* Whether the namepace is an inline namespace. */ #define DECL_NAMESPACE_INLINE_P(NODE) \ TREE_LANG_FLAG_0 (NAMESPACE_DECL_CHECK (NODE)) Index: name-lookup.c =================================================================== --- name-lookup.c (revision 248094) +++ name-lookup.c (working copy) @@ -3327,6 +3327,25 @@ do_local_using_decl (tree decl, tree sco cp_emit_debug_info_for_using (orig_decl, current_scope()); } +/* Returns true if ANCESTOR encloses DESCENDANT, including matching. + Both are namespaces. */ + +bool +is_nested_namespace (tree ancestor, tree descendant, bool inline_only) +{ + int depth = SCOPE_DEPTH (ancestor); + + if (!depth && !inline_only) + /* The global namespace encloses everything. */ + return true; + + while (SCOPE_DEPTH (descendant) > depth + && (!inline_only || DECL_NAMESPACE_INLINE_P (descendant))) + descendant = CP_DECL_CONTEXT (descendant); + + return ancestor == descendant; +} + /* Returns true if ROOT (a namespace, class, or function) encloses CHILD. CHILD may be either a class type or a namespace. */ @@ -3343,19 +3362,22 @@ is_ancestor (tree root, tree child) if (root == global_namespace) return true; - while (true) + /* Search until we reach namespace scope. */ + while (TREE_CODE (child) != NAMESPACE_DECL) { - /* If we've run out of scopes, stop. */ - if (!child) - return false; /* If we've reached the ROOT, it encloses CHILD. */ if (root == child) return true; /* Go out one level. */ if (TYPE_P (child)) child = TYPE_NAME (child); - child = DECL_CONTEXT (child); + child = CP_DECL_CONTEXT (child); } + + if (TREE_CODE (root) == NAMESPACE_DECL) + return is_nested_namespace (root, child); + + return false; } /* Enter the class or namespace scope indicated by T suitable for name @@ -4076,7 +4098,7 @@ set_decl_namespace (tree decl, tree scop scope = ORIGINAL_NAMESPACE (scope); /* It is ok for friends to be qualified in parallel space. */ - if (!friendp && !is_ancestor (current_namespace, scope)) + if (!friendp && !is_nested_namespace (current_namespace, scope)) error ("declaration of %qD not in a namespace surrounding %qD", decl, scope); DECL_CONTEXT (decl) = FROB_CONTEXT (scope); @@ -4153,7 +4175,7 @@ set_decl_namespace (tree decl, tree scop } if (found) { - if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found))) + if (!is_nested_namespace (scope, CP_DECL_CONTEXT (found), true)) goto complain; if (DECL_HIDDEN_FRIEND_P (found)) { @@ -6499,6 +6521,11 @@ push_namespace (tree name, bool make_inl if (!ns) { ns = build_lang_decl (NAMESPACE_DECL, name, void_type_node); + SCOPE_DEPTH (ns) = SCOPE_DEPTH (current_namespace) + 1; + if (!SCOPE_DEPTH (ns)) + /* We only allow depth 255. */ + sorry ("cannot nest more than %d namespaces", + SCOPE_DEPTH (current_namespace)); DECL_CONTEXT (ns) = FROB_CONTEXT (current_namespace); new_ns = true; Index: name-lookup.h =================================================================== --- name-lookup.h (revision 248094) +++ name-lookup.h (working copy) @@ -292,6 +292,8 @@ extern void print_binding_stack (void); extern void pop_everything (void); extern void keep_next_level (bool); extern bool is_ancestor (tree ancestor, tree descendant); +extern bool is_nested_namespace (tree parent, tree descendant, + bool inline_only = false); extern tree push_scope (tree); extern void pop_scope (tree); extern tree push_inner_scope (tree); Index: pt.c =================================================================== --- pt.c (revision 248094) +++ pt.c (working copy) @@ -784,9 +784,7 @@ check_specialization_namespace (tree tmp return false; } - if (cxx_dialect < cxx11 - ? is_associated_namespace (current_namespace, tpl_ns) - : is_ancestor (current_namespace, tpl_ns)) + if (is_nested_namespace (current_namespace, tpl_ns, cxx_dialect < cxx11)) /* Same or enclosing namespace. */ return true; else @@ -810,7 +808,7 @@ check_explicit_instantiation_namespace ( /* DR 275: An explicit instantiation shall appear in an enclosing namespace of its template. */ ns = decl_namespace_context (spec); - if (!is_ancestor (current_namespace, ns)) + if (!is_nested_namespace (current_namespace, ns)) permerror (input_location, "explicit instantiation of %qD in namespace %qD " "(which does not enclose namespace %qD)", spec, current_namespace, ns); @@ -2594,8 +2592,8 @@ check_unqualified_spec_or_inst (tree t, { tree tmpl = most_general_template (t); if (DECL_NAMESPACE_SCOPE_P (tmpl) - && !is_associated_namespace (current_namespace, - CP_DECL_CONTEXT (tmpl))) + && !is_nested_namespace (current_namespace, + CP_DECL_CONTEXT (tmpl), true)) { if (processing_specialization) permerror (loc, "explicit specialization of %qD outside its " --------------0A4E07B54A8F8884DD3840C0--