From patchwork Sun Jul 7 02:06:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 1957646 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=MMYyzwHJ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WGrNK4WtKz1xrJ for ; Sun, 7 Jul 2024 12:11:43 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 48B03385DC3C for ; Sun, 7 Jul 2024 02:11:41 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-io1-xd35.google.com (mail-io1-xd35.google.com [IPv6:2607:f8b0:4864:20::d35]) by sourceware.org (Postfix) with ESMTPS id 488143828920 for ; Sun, 7 Jul 2024 02:06:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 488143828920 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 488143828920 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::d35 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720317987; cv=none; b=TY1B5KUGZa3v/3ilIkJEHuaRX5252tmZqcre6Zl/QZSkgS4qDQTp5qybnVhafU+UL5xALj+WuiLsZ5KK/Y9vWBQpU6OkcD3I7cJ1co5Kjhnl6hwKAdAPdNYhLmqMhx6y5oE+6xdgHn0xouBrkauxxknCZf9zcw2OUeg3HPnLcjk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720317987; c=relaxed/simple; bh=0ENXdm1hWf1XgkeR6mRVqLrtBx2/GLjveI3S2vKLPbk=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=h5kW9SvdeKhbfxhhoweYzfNJ07rRq0Sirn+KxUVXw7qVbapsAlONODW1QqfRox870QspCF3YoIZqpGf0MDNxvvUQp6xFf70R2He7jTcdBOKSI1Qq4VkGRTnRcAwOXCFlSufV1aKOQdp4O38plvI0B24Fui6qNYkJTHNHXhlhHsA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-io1-xd35.google.com with SMTP id ca18e2360f4ac-7f67e767f34so56085539f.2 for ; Sat, 06 Jul 2024 19:06:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1720317976; x=1720922776; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=vnndPvxU0r5pboDTEqThL+Y2ufwrPa/PA5Chriu2Y3M=; b=MMYyzwHJ/Rb9ysVaY9fMAM45AYKB7Ayy8GODDcC0B7kemUkR7OYQiwOyTMwTfWBtkZ MZ4dlP2ZMfDwmUlqA30jxEhXPxkojcxRU33+KZncAPLp3ham0Y1KkQdLstaXQo9pwwWg zlk67bzskC/nlc4ahbEIVpEsRuUBgGV+1Gzny44So8Ml5iF5dm5se6/OuqVR7OFonD9z cc7SHuy8Ra2mKdHgyGM+3lRAF8a8Nl/YLSxevyhndWftXVxxkRcM8a3Bq8BilBknA4Oa UNz8lEYtm26kOq3oso8697Vh8lTKAcSSs41dbIs06Ljz6qNEUZL+hvT+TluI3OgTeeYb dH5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720317976; x=1720922776; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vnndPvxU0r5pboDTEqThL+Y2ufwrPa/PA5Chriu2Y3M=; b=XlxtJtKnM0RJX1ufGYvRTLzwoo0qh4r6QvSRFVwN/gW2vxyb2mJEeYBEstZk/uGLGS alkhlD4C8u20zHvuwVk3gpETLrrDYW6WGz/jYXPTut5uakVdcWCo7NkuswzNT4c6DGkw qdsKNLHQxjKzqoOFzO6fb6KvtN+pOcWkZpdLqxxzXDi/QljemhpDHmIru7NR+EMzgoxL AbWd1A+mZnVKNYfqd56Nb0vIiwMZV/75l+BawbZR0x7FtzWP8AazqBA61gGAk+cGzAwA F9xdnJ9I/avo3F0sFVLY1E8kOGuadkDsFQZ0eUDLXjZOO8UYJW8aJu6HHhW2fXduJI4u 6VuQ== X-Gm-Message-State: AOJu0YzXmgQ9Y2LHQpMy9IoJu2xvQlnUtpX+AjbzHXZ43GAV/xFXVEZv OvO7O6Kkjlenl3J1OiCgPBKWM0rdXMvMqwwno1ZF/w/13dy77IHO5HlKtg== X-Google-Smtp-Source: AGHT+IFx5pyaC2RtaTSeRHMgj/h/2W7aqClxzd8lZ2HQX6W2xCP6eyG1U1asnAPV+XoqO143v8Ej+g== X-Received: by 2002:a05:6602:1b12:b0:7f6:f93d:e692 with SMTP id ca18e2360f4ac-7f6f93de9f5mr362541739f.15.1720317975970; Sat, 06 Jul 2024 19:06:15 -0700 (PDT) Received: from Thaum. (125-209-140-42.tpgi.com.au. [125.209.140.42]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2c99aa607e4sm5635571a91.40.2024.07.06.19.06.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Jul 2024 19:06:15 -0700 (PDT) Message-ID: <6689f817.170a0220.7c1d3.1348@mx.google.com> X-Google-Original-Message-ID: Date: Sun, 7 Jul 2024 12:06:11 +1000 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell Subject: [PATCH 1/3] c++: Introduce USING_DECLs for non-function usings [PR114683] MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- With modules, a non-function using-declaration is not completely interchangable with the declaration that it refers to; in particular, such a using-declaration may be exported without revealing the name of the entity it refers to. This patch fixes this by building USING_DECLs for all using-declarations that bind a non-function. These new decls can than have purviewness and exportingness attached to them without affecting the decl that they refer to. We do this for all such usings, not just usings that may be revealed in a module; this way we can verify the change in representation against the (more comprehensive) non-modules testsuites, and in a future patch we can use the locations of these using-decls to enhance relevant diagnostics. Another possible approach would be to reuse OVERLOADs for this, as is already done within add_binding_entity for modules. I didn't do this because lots of code (as well as the names of the accessors) makes assumptions that OVERLOADs refer to function overload sets, and so splitting this up reduced semantic burden and made it easier to avoid unintentional changes. This did mean that we need to move out the definitions of ovl_iterator::{purview,exporting}_p, because the structures for module decls are declared later on in cp-tree.h. Building USING_DECLs changed a couple of code paths when adjusting bindings; in particular, pushdecl recognises global using-declarations as usings now, and so checks fall through to update_binding. To not regress g++.dg/lookup/linkage2.C the checks for 'extern' declarations no longer were sufficient (they don't handle 'extern "C"'); but duplicate_decls performed all the relevant checks anyway. Otherwise in general we strip using-decls from all lookup_* functions where necessary. Over time for diagnostics purposes it would probably be good to slowly revert this (especially e.g. lookup_elaborated_type causes some diagnostic quality regressions here) but this patch doesn't do so to minimise churn. PR c++/114683 gcc/cp/ChangeLog: * cp-tree.h (class ovl_iterator): Move definitions of purview_p and exporting_p to name-lookup.cc. * module.cc (depset::hash::add_binding_entity): Strip using-decls, remove workarounds. (enum ct_bind_flags): Remove unnecessary cbf_wrapped flag. (module_state::write_cluster): Likewise. (module_state::read_cluster): Build USING_DECL for non-function usings. * name-lookup.cc (get_fixed_binding_slot): Strip USING_DECLs. (name_lookup::process_binding): Strip USING_DECLs. (name_lookup::process_module_binding): Remove workaround. (update_binding): Strip USING_DECLs, remove incorrect check for non-extern variables. (ovl_iterator::purview_p): Support USING_DECLs. (ovl_iterator::exporting_p): Support USING_DECLs. (walk_module_binding): Handle stat hack type. (do_nonmember_using_decl): Strip USING_DECLs when comparing; build USING_DECLs for non-function usings rather than binding directly. (get_namespace_binding): Strip USING_DECLs. (lookup_name): Strip USING_DECLs. (lookup_elaborated_type): Strip USING_DECLs. * decl.cc (poplevel): Still support -Wunused for using-decls. (lookup_and_check_tag): Remove unnecessary strip_using_decl. * parser.cc (cp_parser_template_name): Likewise. (cp_parser_nonclass_name): Likewise. (cp_parser_class_name): Likewise. gcc/testsuite/ChangeLog: * g++.dg/lookup/using29.C: Update errors. * g++.dg/lookup/using53.C: Update errors, add XFAILs. * g++.dg/modules/using-22_b.C: Remove xfails. * g++.dg/warn/Wunused-var-18.C: Update error location. * g++.dg/lookup/using68.C: New test. * g++.dg/modules/using-24_a.C: New test. * g++.dg/modules/using-24_b.C: New test. * g++.dg/modules/using-enum-4_a.C: New test. * g++.dg/modules/using-enum-4_b.C: New test. * g++.dg/modules/using-enum-4_c.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/cp-tree.h | 13 +- gcc/cp/decl.cc | 18 +- gcc/cp/module.cc | 78 +++++---- gcc/cp/name-lookup.cc | 156 ++++++++++-------- gcc/cp/parser.cc | 6 - gcc/testsuite/g++.dg/lookup/using29.C | 6 +- gcc/testsuite/g++.dg/lookup/using53.C | 20 ++- gcc/testsuite/g++.dg/lookup/using68.C | 7 + gcc/testsuite/g++.dg/modules/using-22_b.C | 6 +- gcc/testsuite/g++.dg/modules/using-24_a.C | 15 ++ gcc/testsuite/g++.dg/modules/using-24_b.C | 12 ++ gcc/testsuite/g++.dg/modules/using-enum-4_a.C | 13 ++ gcc/testsuite/g++.dg/modules/using-enum-4_b.C | 7 + gcc/testsuite/g++.dg/modules/using-enum-4_c.C | 11 ++ gcc/testsuite/g++.dg/warn/Wunused-var-18.C | 4 +- 15 files changed, 231 insertions(+), 141 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/using68.C create mode 100644 gcc/testsuite/g++.dg/modules/using-24_a.C create mode 100644 gcc/testsuite/g++.dg/modules/using-24_b.C create mode 100644 gcc/testsuite/g++.dg/modules/using-enum-4_a.C create mode 100644 gcc/testsuite/g++.dg/modules/using-enum-4_b.C create mode 100644 gcc/testsuite/g++.dg/modules/using-enum-4_c.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4bb3e9c4989..8732b7dc71b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -889,21 +889,12 @@ class ovl_iterator { return (TREE_CODE (ovl) == USING_DECL || (TREE_CODE (ovl) == OVERLOAD && OVL_USING_P (ovl))); } - /* Whether this using is in the module purview. */ - bool purview_p () const - { - return OVL_PURVIEW_P (get_using ()); - } - /* Whether this using is being exported. */ - bool exporting_p () const - { - return OVL_EXPORT_P (get_using ()); - } - bool hidden_p () const { return TREE_CODE (ovl) == OVERLOAD && OVL_HIDDEN_P (ovl); } + bool purview_p () const; + bool exporting_p () const; public: tree remove_node (tree head) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 29616100cfe..5a823e2f94c 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -702,12 +702,13 @@ poplevel (int keep, int reverse, int functionbody) /* There are cases where D itself is a TREE_LIST. See in push_local_binding where the list of decls returned by getdecls is built. */ - decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d; + tree udecl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d; + decl = strip_using_decl (udecl); tree type = TREE_TYPE (decl); if (VAR_P (decl) - && (! TREE_USED (decl) || !DECL_READ_P (decl)) - && ! DECL_IN_SYSTEM_HEADER (decl) + && (!TREE_USED (decl) || !DECL_READ_P (decl)) + && !DECL_IN_SYSTEM_HEADER (udecl) /* For structured bindings, consider only real variables, not subobjects. */ && (DECL_DECOMPOSITION_P (decl) ? DECL_DECOMP_IS_BASE (decl) @@ -720,14 +721,14 @@ poplevel (int keep, int reverse, int functionbody) || lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl))))) { - if (! TREE_USED (decl)) + if (!TREE_USED (decl)) { if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl)) - warning_at (DECL_SOURCE_LOCATION (decl), + warning_at (DECL_SOURCE_LOCATION (udecl), OPT_Wunused_variable, "unused structured binding declaration"); else - warning_at (DECL_SOURCE_LOCATION (decl), + warning_at (DECL_SOURCE_LOCATION (udecl), OPT_Wunused_variable, "unused variable %qD", decl); suppress_warning (decl, OPT_Wunused_variable); } @@ -737,11 +738,11 @@ poplevel (int keep, int reverse, int functionbody) && errorcount == unused_but_set_errorcount) { if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl)) - warning_at (DECL_SOURCE_LOCATION (decl), + warning_at (DECL_SOURCE_LOCATION (udecl), OPT_Wunused_but_set_variable, "structured " "binding declaration set but not used"); else - warning_at (DECL_SOURCE_LOCATION (decl), + warning_at (DECL_SOURCE_LOCATION (udecl), OPT_Wunused_but_set_variable, "variable %qD set but not used", decl); unused_but_set_errorcount = errorcount; @@ -16495,7 +16496,6 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, /* First try ordinary name lookup, ignoring hidden class name injected via friend declaration. */ decl = lookup_name (name, LOOK_want::TYPE); - decl = strip_using_decl (decl); /* If that fails, the name will be placed in the smallest non-class, non-function-prototype scope according to 3.3.1/5. We may already have a hidden name declared as friend in this diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index dc5d046f04d..f5966fc8c1c 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -13125,6 +13125,7 @@ bool depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) { auto data = static_cast (data_); + decl = strip_using_decl (decl); if (!(TREE_CODE (decl) == NAMESPACE_DECL && !DECL_NAMESPACE_ALIAS (decl))) { @@ -13159,18 +13160,14 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) /* Ignore NTTP objects. */ return false; - bool unscoped_enum_const_p = false; if (!(flags & WMB_Using) && CP_DECL_CONTEXT (decl) != data->ns) { - /* A using that lost its wrapper or an unscoped enum - constant. */ - /* FIXME: Ensure that unscoped enums are differentiated from - 'using enum' declarations when PR c++/114683 is fixed. */ - unscoped_enum_const_p = (TREE_CODE (decl) == CONST_DECL); + /* An unscoped enum constant implicitly brought into the containing + namespace. We treat this like a using-decl. */ + gcc_checking_assert (TREE_CODE (decl) == CONST_DECL); + flags = WMB_Flags (flags | WMB_Using); - if (DECL_MODULE_EXPORT_P (TREE_CODE (decl) == CONST_DECL - ? TYPE_NAME (TREE_TYPE (decl)) - : STRIP_TEMPLATE (decl))) + if (DECL_MODULE_EXPORT_P (TYPE_NAME (TREE_TYPE (decl)))) flags = WMB_Flags (flags | WMB_Export); } @@ -13228,8 +13225,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) if (flags & WMB_Using) { decl = ovl_make (decl, NULL_TREE); - if (!unscoped_enum_const_p) - OVL_USING_P (decl) = true; + OVL_USING_P (decl) = true; OVL_PURVIEW_P (decl) = true; if (flags & WMB_Export) OVL_EXPORT_P (decl) = true; @@ -13253,12 +13249,8 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) data->met_namespace = true; if (data->hash->add_namespace_entities (decl, data->partitions)) { - /* It contains an exported thing, so it is exported. - - FIXME we have to set DECL_MODULE_PURVIEW_P instead of asserting - that it is already set because of the c++/114683 issue with - exported using-declarations; see do_nonmember_using_decl. */ - DECL_MODULE_PURVIEW_P (decl) = true; + /* It contains an exported thing, so it is exported. */ + gcc_checking_assert (DECL_MODULE_PURVIEW_P (decl)); DECL_MODULE_EXPORT_P (decl) = true; } @@ -14967,7 +14959,6 @@ enum ct_bind_flags cbf_export = 0x1, /* An exported decl. */ cbf_hidden = 0x2, /* A hidden (friend) decl. */ cbf_using = 0x4, /* A using decl. */ - cbf_wrapped = 0x8, /* ... that is wrapped. */ }; /* DEP belongs to a different cluster, seed it to prevent @@ -15130,13 +15121,9 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, if (!(TREE_CODE (bound) == CONST_DECL && UNSCOPED_ENUM_P (TREE_TYPE (bound)) && decl == TYPE_NAME (TREE_TYPE (bound)))) - { - /* An unscope enumerator in its enumeration's - scope is not a using. */ - flags |= cbf_using; - if (OVL_USING_P (ovl)) - flags |= cbf_wrapped; - } + /* An unscoped enumerator in its enumeration's + scope is not a using. */ + flags |= cbf_using; if (OVL_EXPORT_P (ovl)) flags |= cbf_export; } @@ -15303,13 +15290,46 @@ module_state::read_cluster (unsigned snum) /* Stat hack. */ if (type || !DECL_IMPLICIT_TYPEDEF_P (decl)) sec.set_overrun (); - type = decl; + + type = build_lang_decl_loc (UNKNOWN_LOCATION, + USING_DECL, + DECL_NAME (decl), + NULL_TREE); + USING_DECL_DECLS (type) = decl; + USING_DECL_SCOPE (type) = CP_DECL_CONTEXT (decl); + DECL_CONTEXT (type) = ns; + + DECL_MODULE_PURVIEW_P (type) = true; + if (flags & cbf_export) + DECL_MODULE_EXPORT_P (type) = true; } else { - if (decls - || (flags & (cbf_hidden | cbf_wrapped)) - || DECL_FUNCTION_TEMPLATE_P (decl)) + if ((flags & cbf_using) && + !DECL_DECLARES_FUNCTION_P (decl)) + { + /* We should only see a single non-function using-decl + for a binding; more than that would clash. */ + if (decls) + sec.set_overrun (); + + /* FIXME: Propagate the location of the using-decl + for use in diagnostics. */ + decls = build_lang_decl_loc (UNKNOWN_LOCATION, + USING_DECL, + DECL_NAME (decl), + NULL_TREE); + USING_DECL_DECLS (decls) = decl; + USING_DECL_SCOPE (decls) = CP_DECL_CONTEXT (decl); + DECL_CONTEXT (decls) = ns; + + DECL_MODULE_PURVIEW_P (decls) = true; + if (flags & cbf_export) + DECL_MODULE_EXPORT_P (decls) = true; + } + else if (decls + || (flags & (cbf_hidden | cbf_using)) + || DECL_FUNCTION_TEMPLATE_P (decl)) { decls = ovl_make (decl, decls); if (flags & cbf_using) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index b57893116eb..ddb4c0fe1c8 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -281,10 +281,11 @@ get_fixed_binding_slot (tree *slot, tree name, unsigned ix, int create) /* Propagate global & module entities to the global and partition slots. */ - if (tree type = MAYBE_STAT_TYPE (orig)) + if (tree type = strip_using_decl (MAYBE_STAT_TYPE (orig))) init_global_partition (cluster, type); - for (ovl_iterator iter (MAYBE_STAT_DECL (orig)); iter; ++iter) + for (ovl_iterator iter (strip_using_decl (MAYBE_STAT_DECL (orig))); + iter; ++iter) { tree decl = *iter; @@ -767,6 +768,9 @@ name_lookup::process_binding (tree new_val, tree new_type) && (want & LOOK_want::TYPE_NAMESPACE) == LOOK_want::NAMESPACE) new_type = NULL_TREE; + new_val = strip_using_decl (new_val); + new_type = strip_using_decl (new_type); + /* Do we really see a value? */ if (new_val) switch (TREE_CODE (new_val)) @@ -827,17 +831,6 @@ name_lookup::process_module_binding (tree new_val, tree new_type, marker |= 2; } - /* add_binding_entity wraps decls brought in by 'using' in an OVERLOAD even - for non-functions; strip it now. - ??? Why isn't it represented with a USING_DECL? Or do we want to use - OVERLOAD for using more widely to address 114683? */ - if (new_val && TREE_CODE (new_val) == OVERLOAD - && !DECL_DECLARES_FUNCTION_P (OVL_FUNCTION (new_val))) - { - gcc_checking_assert (OVL_USING_P (new_val) && !OVL_CHAIN (new_val)); - new_val = OVL_FUNCTION (new_val); - } - if (new_type || new_val) marker |= process_binding (new_val, new_type); @@ -2998,6 +2991,7 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot, if (old == error_mark_node) old = NULL_TREE; + old = strip_using_decl (old); if (DECL_IMPLICIT_TYPEDEF_P (decl)) { @@ -3102,11 +3096,7 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot, } else if (TREE_CODE (old) == VAR_DECL) { - /* There can be two block-scope declarations of the same - variable, so long as they are `extern' declarations. */ - if (!DECL_EXTERNAL (old) || !DECL_EXTERNAL (decl)) - goto conflict; - else if (tree match = duplicate_decls (decl, old)) + if (tree match = duplicate_decls (decl, old)) { gcc_checking_assert (!hide_value && !hiding); return match; @@ -4205,6 +4195,28 @@ lookup_class_binding (tree klass, tree name) return found; } +/* Whether this using is declared in the module purview. */ + +bool +ovl_iterator::purview_p () const +{ + gcc_checking_assert (using_p ()); + if (TREE_CODE (ovl) == USING_DECL) + return DECL_MODULE_PURVIEW_P (ovl); + return OVL_PURVIEW_P (ovl); +} + +/* Whether this using is exported from this module. */ + +bool +ovl_iterator::exporting_p () const +{ + gcc_checking_assert (using_p ()); + if (TREE_CODE (ovl) == USING_DECL) + return DECL_MODULE_EXPORT_P (ovl); + return OVL_EXPORT_P (ovl); +} + /* Given a namespace-level binding BINDING, walk it, calling CALLBACK for all decls of the current module. When partitions are involved, decls might be mentioned more than once. Return the accumulation of @@ -4215,8 +4227,6 @@ walk_module_binding (tree binding, bitmap partitions, bool (*callback) (tree decl, WMB_Flags, void *data), void *data) { - // FIXME: We don't quite deal with using decls naming stat hack - // type. tree current = binding; unsigned count = 0; @@ -4229,6 +4239,14 @@ walk_module_binding (tree binding, bitmap partitions, WMB_Flags flags = WMB_None; if (STAT_TYPE_HIDDEN_P (current)) flags = WMB_Flags (flags | WMB_Hidden); + if (TREE_CODE (type) == USING_DECL) + { + flags = WMB_Flags (flags | WMB_Using); + if (DECL_MODULE_PURVIEW_P (type)) + flags = WMB_Flags (flags | WMB_Purview); + if (DECL_MODULE_EXPORT_P (type)) + flags = WMB_Flags (flags | WMB_Export); + } count += callback (type, flags, data); decl_hidden = STAT_DECL_HIDDEN_P (current); } @@ -4300,7 +4318,14 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Dups); if (STAT_TYPE_HIDDEN_P (bind)) flags = WMB_Flags (flags | WMB_Hidden); - + if (TREE_CODE (btype) == USING_DECL) + { + flags = WMB_Flags (flags | WMB_Using); + if (DECL_MODULE_PURVIEW_P (btype)) + flags = WMB_Flags (flags | WMB_Purview); + if (DECL_MODULE_EXPORT_P (btype)) + flags = WMB_Flags (flags | WMB_Export); + } count += callback (btype, flags, data); } bool part_hidden = STAT_DECL_HIDDEN_P (bind); @@ -5201,7 +5226,7 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p, /* Shift the old and new bindings around so we're comparing class and enumeration names to each other. */ - if (value && DECL_IMPLICIT_TYPEDEF_P (value)) + if (value && DECL_IMPLICIT_TYPEDEF_P (strip_using_decl (value))) { type = value; value = NULL_TREE; @@ -5306,61 +5331,51 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p, else if (value /* Ignore anticipated builtins. */ && !anticipated_builtin_p (value) - && (fn_scope_p || !decls_match (lookup.value, value))) + && (fn_scope_p + || !decls_match (lookup.value, strip_using_decl (value)))) { diagnose_name_conflict (lookup.value, value); failed = true; } else if (insert_p) { - /* FIXME: Handle exporting declarations from a different scope - without also marking those declarations as exported. - This will require not just binding directly to the underlying - value; see c++/114683 and c++/114685. We allow the extra exports - for now as this doesn't (currently) cause ICEs - later down the line, but this should be revisited. */ - if (revealing_p) - { - if (module_exporting_p () - && check_can_export_using_decl (lookup.value) - && !DECL_MODULE_EXPORT_P (lookup.value)) - { - /* We're redeclaring the same value, but this time as - newly exported: make sure to mark it as such. */ - if (TREE_CODE (lookup.value) == TEMPLATE_DECL) - DECL_MODULE_EXPORT_P (DECL_TEMPLATE_RESULT (lookup.value)) = true; - DECL_MODULE_EXPORT_P (lookup.value) = true; - } - /* We're also revealing this declaration with a using-decl, - so mark it as purview to ensure it's emitted. */ - tree inner = STRIP_TEMPLATE (lookup.value); - retrofit_lang_decl (inner); - DECL_MODULE_PURVIEW_P (inner) = true; - } - value = lookup.value; + /* A using-decl does not necessarily have the same purview-ness or + exporting as the declaration it reveals, so build a USING_DECL + that we can attach this information to. This also gives us a + location for the using-decl that we can use in diagnostics. */ + value = build_lang_decl (USING_DECL, lookup.name, NULL_TREE); + USING_DECL_DECLS (value) = lookup.value; + USING_DECL_SCOPE (value) = CP_DECL_CONTEXT (lookup.value); + DECL_CONTEXT (value) = current_scope (); + + DECL_MODULE_PURVIEW_P (value) = module_purview_p (); + if (revealing_p + && module_exporting_p () + && check_can_export_using_decl (lookup.value)) + DECL_MODULE_EXPORT_P (value) = true; } - + /* Now the type binding. */ if (lookup.type) { - if (type && !decls_match (lookup.type, type)) + if (type && !decls_match (lookup.type, strip_using_decl (type))) { diagnose_name_conflict (lookup.type, type); failed = true; } else if (insert_p) { - if (revealing_p) - { - /* As with revealing value bindings. */ - if (module_exporting_p () - && check_can_export_using_decl (lookup.type) - && lookup.type == type) - DECL_MODULE_EXPORT_P (lookup.type) = true; - retrofit_lang_decl (lookup.type); - DECL_MODULE_PURVIEW_P (lookup.type) = true; - } - type = lookup.type; + /* As with revealing value bindings. */ + type = build_lang_decl (USING_DECL, lookup.name, NULL_TREE); + USING_DECL_DECLS (type) = lookup.type; + USING_DECL_SCOPE (type) = CP_DECL_CONTEXT (lookup.type); + DECL_CONTEXT (type) = current_scope (); + + DECL_MODULE_PURVIEW_P (type) = module_purview_p (); + if (revealing_p + && module_exporting_p () + && check_can_export_using_decl (lookup.type)) + DECL_MODULE_EXPORT_P (type) = true; } } @@ -6217,7 +6232,7 @@ get_namespace_binding (tree ns, tree name) if (TREE_CODE (ret) == BINDING_VECTOR) ret = BINDING_VECTOR_CLUSTER (ret, 0).slots[0]; if (ret) - ret = MAYBE_STAT_DECL (ret); + ret = strip_using_decl (MAYBE_STAT_DECL (ret)); } return ret; @@ -8000,7 +8015,7 @@ lookup_name (tree name, LOOK_where where, LOOK_want want) if (binding) { - val = binding; + val = strip_using_decl (binding); break; } } @@ -8073,7 +8088,7 @@ lookup_elaborated_type (tree name, TAG_how how) typedef struct C {} C; correctly. */ - if (tree type = iter->type) + if (tree type = strip_using_decl (iter->type)) { if (qualify_lookup (type, LOOK_want::TYPE) && (how != TAG_how::CURRENT_ONLY @@ -8089,7 +8104,8 @@ lookup_elaborated_type (tree name, TAG_how how) } else { - if (qualify_lookup (iter->value, LOOK_want::TYPE) + tree value = strip_using_decl (iter->value); + if (qualify_lookup (value, LOOK_want::TYPE) && (how != TAG_how::CURRENT_ONLY || !INHERITED_VALUE_BINDING_P (iter))) { @@ -8097,7 +8113,7 @@ lookup_elaborated_type (tree name, TAG_how how) /* It is no longer a hidden binding. */ HIDDEN_TYPE_BINDING_P (iter) = false; - return iter->value; + return value; } } } @@ -8121,7 +8137,7 @@ lookup_elaborated_type (tree name, TAG_how how) if (bind) { /* If this is the kind of thing we're looking for, we're done. */ - if (tree type = MAYBE_STAT_TYPE (bind)) + if (tree type = strip_using_decl (MAYBE_STAT_TYPE (bind))) { if (how != TAG_how::HIDDEN_FRIEND) /* No longer hidden. */ @@ -8129,7 +8145,7 @@ lookup_elaborated_type (tree name, TAG_how how) return type; } - else if (tree decl = MAYBE_STAT_DECL (bind)) + else if (tree decl = strip_using_decl (MAYBE_STAT_DECL (bind))) { if (qualify_lookup (decl, LOOK_want::TYPE)) { @@ -8210,10 +8226,10 @@ lookup_elaborated_type (tree name, TAG_how how) } if (type && qualify_lookup (type, LOOK_want::TYPE)) - return type; + return strip_using_decl (type); if (bind && qualify_lookup (bind, LOOK_want::TYPE)) - return bind; + return strip_using_decl (bind); } if (!module_purview_p ()) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 31ae9c2fb54..229a0b2c96e 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -19506,8 +19506,6 @@ cp_parser_template_name (cp_parser* parser, /*ambiguous_decls=*/NULL, token->location); - decl = strip_using_decl (decl); - /* 13.3 [temp.names] A < is interpreted as the delimiter of a template-argument-list if it follows a name that is not a conversion-function-id and @@ -21140,8 +21138,6 @@ cp_parser_nonclass_name (cp_parser* parser) /* Look up the type-name. */ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location); - type_decl = strip_using_decl (type_decl); - if (TREE_CODE (type_decl) != TYPE_DECL && (objc_is_id (identifier) || objc_is_class_name (identifier))) { @@ -26916,8 +26912,6 @@ cp_parser_class_name (cp_parser *parser, decl = TYPE_NAME (decl); } - decl = strip_using_decl (decl); - /* Check to see that it is really the name of a class. */ if (TREE_CODE (decl) == TEMPLATE_ID_EXPR && identifier_p (TREE_OPERAND (decl, 0)) diff --git a/gcc/testsuite/g++.dg/lookup/using29.C b/gcc/testsuite/g++.dg/lookup/using29.C index 428021cf778..697a654aacb 100644 --- a/gcc/testsuite/g++.dg/lookup/using29.C +++ b/gcc/testsuite/g++.dg/lookup/using29.C @@ -51,7 +51,7 @@ struct I2 : H struct J { - struct type {}; + struct type {}; // { dg-message "previous" } }; struct K : J @@ -62,8 +62,8 @@ struct K : J struct L : J { - using J::type; // { dg-message "previous" } - struct type {}; // { dg-error "conflicts" } + using J::type; + struct type {}; // { dg-error "redefinition" } }; struct M diff --git a/gcc/testsuite/g++.dg/lookup/using53.C b/gcc/testsuite/g++.dg/lookup/using53.C index f9e59e66cea..e91829e939a 100644 --- a/gcc/testsuite/g++.dg/lookup/using53.C +++ b/gcc/testsuite/g++.dg/lookup/using53.C @@ -1,21 +1,23 @@ // PR c++/20420 +// FIXME: These error messages aren't great, rather than multiple definition +// we should talk about conflicting declarations with the using-decl. class B { protected: - enum E { E1, E2, E3 }; - struct S { int i; E e; }; + enum E { E1, E2, E3 }; // { dg-message "previous" } + struct S { int i; E e; }; // { dg-message "previous" } }; class D : private B { public: - using B::E; // { dg-message "previous" } - using B::S; // { dg-message "previous" } + using B::E; + using B::S; private: - enum E {}; // { dg-error "conflicts" } - struct S {}; // { dg-error "conflicts" } + enum E {}; // { dg-error "multiple definition" } + struct S {}; // { dg-error "redefinition" } }; template @@ -30,11 +32,11 @@ template class DT : private BT { public: - using BT::E; // { dg-message "previous" } + using BT::E; // { dg-message "previous" "PR c++/115806" { xfail *-*-* } } using BT::S; // { dg-message "previous" } private: - enum E {}; // { dg-error "conflicts" } + enum E {}; // { dg-error "conflicts" "PR c++/115806" { xfail *-*-* } } struct S {}; // { dg-error "conflicts" } }; @@ -50,5 +52,5 @@ void f () { using N::i; - using N::i; // { dg-error "redeclaration" } + using N::i; // { dg-bogus "conflicts" "See P1787 (CWG36)" { xfail *-*-* } } } diff --git a/gcc/testsuite/g++.dg/lookup/using68.C b/gcc/testsuite/g++.dg/lookup/using68.C new file mode 100644 index 00000000000..6eb2be5c19c --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using68.C @@ -0,0 +1,7 @@ +// { dg-do compile } + +struct S {}; // { dg-message "previous" } +void foo() { + using ::S; + struct S {}; // { dg-error "redefinition" } +} diff --git a/gcc/testsuite/g++.dg/modules/using-22_b.C b/gcc/testsuite/g++.dg/modules/using-22_b.C index 0b66f4ad6b0..be122aa6ffa 100644 --- a/gcc/testsuite/g++.dg/modules/using-22_b.C +++ b/gcc/testsuite/g++.dg/modules/using-22_b.C @@ -7,7 +7,9 @@ int main() std::basic_string s; // The inline namespace should not be exported, only the 'using' in std. - std::__cxx11::basic_string s2; // { dg-error "has not been declared" "" { xfail *-*-* } } + std::__cxx11::basic_string s2; // { dg-error "has not been declared" } // The non-exported using should also not be visible. - foo::basic_string s3; // { dg-error "has not been declared" "" { xfail *-*-* } } + foo::basic_string s3; // { dg-error "has not been declared" } } + +// { dg-prune-output "expected primary-expression" } diff --git a/gcc/testsuite/g++.dg/modules/using-24_a.C b/gcc/testsuite/g++.dg/modules/using-24_a.C new file mode 100644 index 00000000000..872f4fc8ab4 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-24_a.C @@ -0,0 +1,15 @@ +// { dg-additional-options "-fmodules-ts -Wno-global-module" } +// { dg-module-cmi M } + +module; + +namespace foo { + struct S {} S; +} + +export module M; + +namespace bar { + export using foo::S; + export using X = struct foo::S; +} diff --git a/gcc/testsuite/g++.dg/modules/using-24_b.C b/gcc/testsuite/g++.dg/modules/using-24_b.C new file mode 100644 index 00000000000..ea80b4cd667 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-24_b.C @@ -0,0 +1,12 @@ +// { dg-additional-options "-fmodules-ts" } + +import M; +namespace foo {} + +int main() { + struct bar::S a = bar::S; + bar::X b = bar::S; + + struct foo::S c; // { dg-error "does not name a type" } + auto d = foo::S; // { dg-error "not a member" } +} diff --git a/gcc/testsuite/g++.dg/modules/using-enum-4_a.C b/gcc/testsuite/g++.dg/modules/using-enum-4_a.C new file mode 100644 index 00000000000..071f5ff797b --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-enum-4_a.C @@ -0,0 +1,13 @@ +// PR c++/114683 +// { dg-do compile { target c++20 } } +// { dg-additional-options "-fmodules-ts -Wno-global-module" } +// { dg-module-cmi M:a } + +module; +namespace foo { + enum class a { x, y, z }; +} +export module M:a; +namespace bar { + export using enum foo::a; +} diff --git a/gcc/testsuite/g++.dg/modules/using-enum-4_b.C b/gcc/testsuite/g++.dg/modules/using-enum-4_b.C new file mode 100644 index 00000000000..38e6081bf58 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-enum-4_b.C @@ -0,0 +1,7 @@ +// PR c++/114683 +// { dg-do compile { target c++20 } } +// { dg-additional-options "-fmodules-ts" } +// { dg-module-cmi M } + +export module M; +export import :a; diff --git a/gcc/testsuite/g++.dg/modules/using-enum-4_c.C b/gcc/testsuite/g++.dg/modules/using-enum-4_c.C new file mode 100644 index 00000000000..4f5965c746a --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-enum-4_c.C @@ -0,0 +1,11 @@ +// PR c++/114683 +// { dg-do compile { target c++20 } } +// { dg-additional-options "-fmodules-ts" } + +import M; +int main() { + auto y = bar::y; + + // This should not be made visible. + auto z = foo::a::z; // { dg-error "not been declared" } +} diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-18.C b/gcc/testsuite/g++.dg/warn/Wunused-var-18.C index 0339663721c..b1bba21e6c4 100644 --- a/gcc/testsuite/g++.dg/warn/Wunused-var-18.C +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-18.C @@ -4,11 +4,11 @@ namespace N { - int i; // { dg-warning "unused variable" } + int i; } void f () { - using N::i; + using N::i; // { dg-warning "unused variable" } } From patchwork Sun Jul 7 02:07:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 1957647 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=BSll6ucp; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WGrTj0kjKz1xr7 for ; Sun, 7 Jul 2024 12:16:25 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 42B893858C52 for ; Sun, 7 Jul 2024 02:16:23 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by sourceware.org (Postfix) with ESMTPS id 5198B3888C6D for ; Sun, 7 Jul 2024 02:07:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5198B3888C6D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5198B3888C6D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::634 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720318086; cv=none; b=ErtecwnQgyAARMW4oWWCOghXjMhEJMXYQeYgbyQV3AbYmZAFjLfwu4/H8cIYckVlfohXTM1bnQsuAb5lls+ya4irA+87KZ4kKVs2mhLUXqk7DgdWXIqxwN30cTdJPHhzqiY/J5x5//RkLcAaolIorUpUhGpMIM6b3qpdpS+hIas= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720318086; c=relaxed/simple; bh=2jtt+lXph0ljlsOpTSXPF+m3nOBdcZWQvUwHjMOCvl0=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=OHhmnasHDDZow5Xs2JfMRQDF3sjDE0j2jQh2FqT6YakIH+4m36hM2Dl3dUBdp4n+TmPXdM+LZbq37hQ+1gHg+YxSNMk8dB/29LHxpWKhvu+Om2+JuBDTO/zdhadQB2W9lyY1IyeLu/kd7vDfNDt/SJ4FGftIgLEY8xrn5Mw6Ti8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-1fb05b0be01so16532385ad.2 for ; Sat, 06 Jul 2024 19:07:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1720318078; x=1720922878; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=Y+MjbBjm4k77UNzoWzqIhze5x63//ifY4pqmPCkYTCM=; b=BSll6ucpYZdGVJuG4H1Q8JR2nmWHdUKmlyI+Bkcq3sarI41j+/FxQx43rYlylpgIIO wvRZfUKA7pChxo90tsNA2GqQa93wO76G50crmFhZEjIezJ/ApMkpCGNBTRa3I76S0lXv MdV4fcKmgPdn9Pom77HnmvxteGsGAEnutM3CuWcf0b7jlalB8TI3k2BLG/whaTY1tJmK Ak5QNMRL2UnxS/SxPaTO3YgjX3d5MNjT1WbEXvJKQ0bv/IKoYZiBymQqPCqB7TWtTQGf 0wkbTm7PgmefgQZIvGWAV5Lw65uiRsS9yccFJMOYgv4ZP2bsxDb0t/RaVHcOi1YvnoCp V6rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720318078; x=1720922878; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Y+MjbBjm4k77UNzoWzqIhze5x63//ifY4pqmPCkYTCM=; b=Km27ZR7xJlVyRBwpCa7WLXed2+cnA4hvj4N1DOgJe+yMgvcuwLXCMa+wi7K8rB+Y6U lQZl29FIA6dAlYimQEiU6AVO5+hVppAlWybW5V580uN+xLdWye80MMW+SR2Y8lOtgdvs McHbcxXdRuJ/c5uO+9YasKr5yWjfUTUTnrajQEhGhkib2Ugojbk+W0nduQghCbk6RTD8 H0g6q5in3MpRvPMaWloZrMtQHWDrun2+6LYrYrFVA8l38WERDMTQZg60S3ZxAjeRZfst Nc/9LS5NzjPoQD7qXz8JPrReXAQRwhmZJQC8Jwgwo7vwojdEY6XL8JSe+BFWMJFswaNv opdA== X-Gm-Message-State: AOJu0YxKF2NoUG4PS+MQY925Vj/1X1ToOPILOYgnsITnC28aZVNaiIwP ryPF/1UqcpBf7nkoSVfeTuqXNUpq6rBc5BhR4E22MJPPPLbJ7Qd9eKlPmQ== X-Google-Smtp-Source: AGHT+IFWr3loT4Ka62c0o9n70h/gnBsgYe0Ow2L+Q/f/tNHoD/ZEv9hmymiUDaRFuHL/F8BsIBEf7g== X-Received: by 2002:a17:902:ce85:b0:1fb:7c7f:6447 with SMTP id d9443c01a7336-1fb7c7f6c77mr14016845ad.25.1720318078080; Sat, 06 Jul 2024 19:07:58 -0700 (PDT) Received: from Thaum. (125-209-140-42.tpgi.com.au. [125.209.140.42]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fb666fdeffsm18253945ad.262.2024.07.06.19.07.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Jul 2024 19:07:57 -0700 (PDT) Message-ID: <6689f87d.170a0220.bb973.3f98@mx.google.com> X-Google-Original-Message-ID: Date: Sun, 7 Jul 2024 12:07:53 +1000 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell Subject: [PATCH 2/3] c++/modules: Handle redefinitions of using-decls MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- This fixes an ICE exposed by supporting exported non-function using-decls. Sometimes when preparing to define a class, xref_tag will find a using-decl belonging to a different namespace, which triggers the checking_assert in modules handling. Ideally I feel that 'lookup_and_check_tag' should be told whether we're about to define the type and handle erroring on redefinitions itself to avoid this issue (and provide better diagnostics by acknowledging the using-declaration), but this is complicated with the current fragmentation of definition checking. So for this patch we just fixup the assertion and ensure that pushdecl properly errors on the conflicting declaration later. gcc/cp/ChangeLog: * decl.cc (xref_tag): Move assertion into condition. * name-lookup.cc (check_module_override): Check for conflicting types and using-decls. gcc/testsuite/ChangeLog: * g++.dg/modules/using-19_a.C: New test. * g++.dg/modules/using-19_b.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/decl.cc | 6 +++-- gcc/cp/name-lookup.cc | 32 ++++++++++++++++------- gcc/testsuite/g++.dg/modules/using-19_a.C | 18 +++++++++++++ gcc/testsuite/g++.dg/modules/using-19_b.C | 10 +++++++ 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/using-19_a.C create mode 100644 gcc/testsuite/g++.dg/modules/using-19_b.C diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 5a823e2f94c..586dda19604 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -16737,12 +16737,14 @@ xref_tag (enum tag_types tag_code, tree name, if (CLASS_TYPE_P (t) && CLASSTYPE_IS_TEMPLATE (t)) maybe_tmpl = CLASSTYPE_TI_TEMPLATE (t); + /* FIXME: we should do a more precise check for redefinitions + of a conflicting using-declaration here, as these diagnostics + are not ideal. */ if (DECL_LANG_SPECIFIC (decl) && DECL_MODULE_IMPORT_P (decl) - && TREE_CODE (CP_DECL_CONTEXT (decl)) == NAMESPACE_DECL) + && CP_DECL_CONTEXT (decl) == current_namespace) { /* Push it into this TU's symbol slot. */ - gcc_checking_assert (current_namespace == CP_DECL_CONTEXT (decl)); if (maybe_tmpl != decl) /* We're in the template parm binding level. Pushtag has logic to slide under that, but we're diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index ddb4c0fe1c8..96d7f938162 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -3782,18 +3782,30 @@ check_module_override (tree decl, tree mvec, bool hiding, /* Errors could cause there to be nothing. */ continue; + tree type = NULL_TREE; if (STAT_HACK_P (bind)) - /* We do not have to check STAT_TYPE here, the xref_tag - machinery deals with that problem. */ - bind = STAT_VISIBLE (bind); + { + /* If there was a matching STAT_TYPE here then xref_tag + should have found it, but we need to check anyway because + a conflicting using-declaration may exist. */ + if (STAT_TYPE_VISIBLE_P (bind)) + type = STAT_TYPE (bind); + bind = STAT_VISIBLE (bind); + } - for (ovl_iterator iter (bind); iter; ++iter) - if (!iter.using_p ()) - { - match = duplicate_decls (decl, *iter, hiding); - if (match) - goto matched; - } + if (type) + { + match = duplicate_decls (decl, strip_using_decl (type), hiding); + if (match) + goto matched; + } + + for (ovl_iterator iter (strip_using_decl (bind)); iter; ++iter) + { + match = duplicate_decls (decl, *iter, hiding); + if (match) + goto matched; + } } if (TREE_PUBLIC (scope) && TREE_PUBLIC (STRIP_TEMPLATE (decl)) diff --git a/gcc/testsuite/g++.dg/modules/using-19_a.C b/gcc/testsuite/g++.dg/modules/using-19_a.C new file mode 100644 index 00000000000..693a70ce7d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-19_a.C @@ -0,0 +1,18 @@ +// { dg-additional-options "-fmodules-ts -Wno-global-module" } +// { dg-module-cmi M } + +module; + +namespace hidden { + struct S {}; + enum E { e }; + void f(); +} + +export module M; +export namespace exposed { + using hidden::S; + using hidden::E; + using hidden::e; + using hidden::f; +} diff --git a/gcc/testsuite/g++.dg/modules/using-19_b.C b/gcc/testsuite/g++.dg/modules/using-19_b.C new file mode 100644 index 00000000000..dbe8d9f3c01 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/using-19_b.C @@ -0,0 +1,10 @@ +// { dg-additional-options "-fmodules-ts" } + +import M; + +namespace exposed { + struct S {}; // { dg-error "redefinition" } + enum E { x }; // { dg-error "multiple definition" } + int e(); // { dg-error "redeclared" } + int f; // { dg-error "redeclared" } +} From patchwork Sun Jul 7 02:13:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 1957648 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=P9puaoPD; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WGrZc0bthz1xpP for ; Sun, 7 Jul 2024 12:20:39 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 26BDD385DDEA for ; Sun, 7 Jul 2024 02:20:37 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-oo1-xc2f.google.com (mail-oo1-xc2f.google.com [IPv6:2607:f8b0:4864:20::c2f]) by sourceware.org (Postfix) with ESMTPS id DDE8A385DDE8 for ; Sun, 7 Jul 2024 02:13:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DDE8A385DDE8 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DDE8A385DDE8 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::c2f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720318450; cv=none; b=XnfEwI3RjipzdCrwj66w10v9a2aYFeVQXqaUSY1jiWOaG1EwBVNTkTSwrguOrT3bbADMwm2TkY6UpQ07m3mSfXTuhv+/MRUlavfn6QklIoNqEXFWyQeIWJdchNvvArD9BLp3xCPPL6yX5UVpfSIqrAnNcib+cc/RWzNyhkeYwd0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1720318450; c=relaxed/simple; bh=XKsA49c7qSgcgNEG4MUMPvE/K1/WV4dFqeim2y9Sqrk=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=w4NtfBEw5g8+6qoshc+XNVof220Ayr91ngFgQBuc1g4ri7qtenvNFtOHSR173KYD72tm4Av5RV/lDLUk8ttkW8ee4NsO5RcnYtYgt0YRZHSaiF8QOfuFNVOIUXHePuOi2PfHmkW5NwoYcPLX7Q0IHautTZ8fUuVzEWmtOpZjYI8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oo1-xc2f.google.com with SMTP id 006d021491bc7-5c66de0c24bso320559eaf.1 for ; Sat, 06 Jul 2024 19:13:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1720318435; x=1720923235; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=nNTcbj8Spnitu7zdasS8EnuTyc7JRMBsS9VWXOOs/Us=; b=P9puaoPDb00gPMGdZa+wwQej2qtBP1pmov2WAFyb9IB3N/Aa2kX+RGxd8VIwFVo015 Rhi47W1TEGIYncUHgn3WosmLSf+eAQv9D1jYgVc4K5WaqJidzxBP+9sgxVJ5aef/8HJY rmjtY2yee5gYoI0GRbsh5iXzQNpLTSwOb943VtdxZzkKHp4cvTwdb17PuMk4wjdNRokX dj9W9iBxlgyhm2F8xIYUHR1mkNPBwl7+jIdWLGZT6pr8c9knS23aFp85FsZQaBikHCzV YrLdL4QMbZWrSXm6472YBfUwRsl0z0+U4yKn9F2UV1ZclnXUlMEIfx13bK653GkCy++E B9nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720318435; x=1720923235; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nNTcbj8Spnitu7zdasS8EnuTyc7JRMBsS9VWXOOs/Us=; b=Kux/WoMDM3y4RODRag1NbgawOrZJfChAAb3LXk3f/tDErvXYourCpr1qnoRgAn28Kc nBitCqeStBfkV/IffBFXWF136UDfbaubaBgsk5dPUGZiwUqr9pYluHRMLc6DBEZYwsc6 ZRsD9I+WZ7U94do+dJt8K8/6iPFGHAakDLdQj8szOzknNTyEu7xbZX2XhlowJaSEHG6y HgOWxP05t7mw9ZrcwjwMQxCN/t2P7A5E5IHBcUAHnobTuvia2u4s0DvW9be5o7a8WcCX WFlbNdjjHQm6ev/3Ht7UiYIvTf6hFC4Wosk9wFZpWO3Nx2a/hz4afJUTZHUggk0gCHCd J+Rw== X-Gm-Message-State: AOJu0Yyp3R7dOKQvfGs2pV7YNNz5hBws201F6AS6fIQrUch5FQ/bY+nH XLO8f3xgCbMjOrtqfClIInxYnjPbW7QMBdLKSkX6Sb2JNI4QpLCaflV8lA== X-Google-Smtp-Source: AGHT+IHU0iNOMZINPCJxJAZHpaSrrmRTmdLkSGF2+1Gg3YrI+faEu2yPE+kgS0RfmJ9tsbt59vomBg== X-Received: by 2002:a05:6870:a54e:b0:254:c95f:cdb6 with SMTP id 586e51a60fabf-25e2bf8cb62mr6698092fac.52.1720318434939; Sat, 06 Jul 2024 19:13:54 -0700 (PDT) Received: from Thaum. (125-209-140-42.tpgi.com.au. [125.209.140.42]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-70b1e0dbf2dsm1829512b3a.67.2024.07.06.19.13.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Jul 2024 19:13:54 -0700 (PDT) Message-ID: <6689f9e2.050a0220.e5708.3f2d@mx.google.com> X-Google-Original-Message-ID: Date: Sun, 7 Jul 2024 12:13:50 +1000 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell Subject: [PATCH 3/3] c++: Add locations to using_p OVERLOADs MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? I have also been working on a patch that uses the locations of using-decls in 'diagnose_name_conflict' and 'duplicate_decls' calls, but that will need a fair bit more work that I'll probaby put off for the meantime. Otherwise, as far as I can tell there's no circumstance when modules-imported namespace-scope USING_DECLs have their locations printed (hence the lack of tests), so I'm happy to defer this patch until I've made something I can actually test. An alternative approach here (rather than giving locations to OVERLOADs) would be to rewrite the modules handling to not using OVERLOADs internally for non-function usings, that way we can attach the location to those USING_DECLs. I went this way because I felt having locations in OVL_USING_P overloads would be useful anyway, but happy to try that route instead if you're uncomfortable increasing the size of most OVERLOADs for something largely unused. -- >8 -- This is used by module streaming to track locations of USING_DECLs (that are internally wrapped and unwrapped as OVERLOADs for consistency with function usings). No testcases with this patch as there aren't any easy ways to actually cause a diagnostic that uses this information yet; that'll come in a later patch. gcc/cp/ChangeLog: * cp-tree.h (OVL_SOURCE_LOCATION): New. (struct tree_overload): Add loc field. (class ovl_iterator): New member function. * module.cc (depset::hash::add_binding_entity): Add parameter. Track locations of usings. (depset::hash::find_dependencies): Note locations of usings. (module_state::write_cluster): Write locations of usings. (module_state::read_cluster): Read locations of usings. * name-lookup.cc (ovl_iterator::source_location): New. (walk_module_binding): Add parameter to callback. Provide locations of usings. * name-lookup.h (walk_module_binding): Add parameter to callback. * ptree.cc (cxx_print_xnode): Write using location. * tree.cc (ovl_insert): Initialise source location for usings. (lookup_maybe_add): Propagate source location for usings. Signed-off-by: Nathaniel Shead --- gcc/cp/cp-tree.h | 6 ++++++ gcc/cp/module.cc | 29 +++++++++++++++++++---------- gcc/cp/name-lookup.cc | 32 ++++++++++++++++++++++++++------ gcc/cp/name-lookup.h | 3 ++- gcc/cp/ptree.cc | 6 ++++++ gcc/cp/tree.cc | 2 ++ 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8732b7dc71b..cc7c1947f9e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -824,6 +824,10 @@ typedef struct ptrmem_cst * ptrmem_cst_t; /* The name of the overload set. */ #define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE)) +/* The source location of this OVL_USING_P overload. */ +#define OVL_SOURCE_LOCATION(NODE) \ + (((struct tree_overload*)OVERLOAD_CHECK (NODE))->loc) + /* Whether this is a set of overloaded functions. TEMPLATE_DECLS are always wrapped in an OVERLOAD, so we don't need to check them here. */ @@ -838,6 +842,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t; struct GTY(()) tree_overload { struct tree_common common; tree function; + location_t loc; }; /* Iterator for a 1 dimensional overload. Permits iterating over the @@ -895,6 +900,7 @@ class ovl_iterator { } bool purview_p () const; bool exporting_p () const; + location_t source_location () const; public: tree remove_node (tree head) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index f5966fc8c1c..5bb3e824acb 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2581,7 +2581,7 @@ public: void add_namespace_context (depset *, tree ns); private: - static bool add_binding_entity (tree, WMB_Flags, void *); + static bool add_binding_entity (tree, WMB_Flags, void *, location_t); public: bool add_namespace_entities (tree ns, bitmap partitions); @@ -13122,7 +13122,8 @@ struct add_binding_data /* Return true if we are, or contain something that is exported. */ bool -depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) +depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_, + location_t loc) { auto data = static_cast (data_); decl = strip_using_decl (decl); @@ -13185,7 +13186,6 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) { if (!(flags & WMB_Hidden)) d->clear_hidden_binding (); - OVL_PURVIEW_P (d->get_entity ()) = true; if (flags & WMB_Export) OVL_EXPORT_P (d->get_entity ()) = true; return bool (flags & WMB_Export); @@ -13229,6 +13229,7 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) OVL_PURVIEW_P (decl) = true; if (flags & WMB_Export) OVL_EXPORT_P (decl) = true; + OVL_SOURCE_LOCATION (decl) = loc; } depset *dep = data->hash->make_dependency @@ -13616,7 +13617,10 @@ depset::hash::find_dependencies (module_state *module) dump.indent (); walker.begin (); if (current->get_entity_kind () == EK_USING) - walker.tree_node (OVL_FUNCTION (decl)); + { + module->note_location (OVL_SOURCE_LOCATION (decl)); + walker.tree_node (OVL_FUNCTION (decl)); + } else if (TREE_VISITED (decl)) /* A global tree. */; else if (item->get_entity_kind () == EK_NAMESPACE) @@ -15114,6 +15118,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, depset *dep = b->deps[jx]; tree bound = dep->get_entity (); unsigned flags = 0; + location_t loc = UNKNOWN_LOCATION; if (dep->get_entity_kind () == depset::EK_USING) { tree ovl = bound; @@ -15126,6 +15131,7 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, flags |= cbf_using; if (OVL_EXPORT_P (ovl)) flags |= cbf_export; + loc = OVL_SOURCE_LOCATION (ovl); } else { @@ -15140,6 +15146,8 @@ module_state::write_cluster (elf_out *to, depset *scc[], unsigned size, gcc_checking_assert (DECL_P (bound)); sec.i (flags); + if (flags & cbf_using) + write_location (sec, loc); sec.tree_node (bound); } @@ -15281,6 +15289,10 @@ module_state::read_cluster (unsigned snum) && (flags & (cbf_using | cbf_export))) sec.set_overrun (); + location_t loc = UNKNOWN_LOCATION; + if (flags & cbf_using) + loc = read_location (sec); + tree decl = sec.tree_node (); if (sec.get_overrun ()) break; @@ -15291,8 +15303,7 @@ module_state::read_cluster (unsigned snum) if (type || !DECL_IMPLICIT_TYPEDEF_P (decl)) sec.set_overrun (); - type = build_lang_decl_loc (UNKNOWN_LOCATION, - USING_DECL, + type = build_lang_decl_loc (loc, USING_DECL, DECL_NAME (decl), NULL_TREE); USING_DECL_DECLS (type) = decl; @@ -15313,10 +15324,7 @@ module_state::read_cluster (unsigned snum) if (decls) sec.set_overrun (); - /* FIXME: Propagate the location of the using-decl - for use in diagnostics. */ - decls = build_lang_decl_loc (UNKNOWN_LOCATION, - USING_DECL, + decls = build_lang_decl_loc (loc, USING_DECL, DECL_NAME (decl), NULL_TREE); USING_DECL_DECLS (decls) = decl; @@ -15339,6 +15347,7 @@ module_state::read_cluster (unsigned snum) OVL_PURVIEW_P (decls) = true; if (flags & cbf_export) OVL_EXPORT_P (decls) = true; + OVL_SOURCE_LOCATION (decls) = loc; } if (flags & cbf_hidden) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 96d7f938162..52c07e46d4f 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -4229,6 +4229,17 @@ ovl_iterator::exporting_p () const return OVL_EXPORT_P (ovl); } +/* The declared source location of this using. */ + +location_t +ovl_iterator::source_location () const +{ + gcc_checking_assert (using_p ()); + if (TREE_CODE (ovl) == USING_DECL) + return DECL_SOURCE_LOCATION (ovl); + return OVL_SOURCE_LOCATION (ovl); +} + /* Given a namespace-level binding BINDING, walk it, calling CALLBACK for all decls of the current module. When partitions are involved, decls might be mentioned more than once. Return the accumulation of @@ -4236,7 +4247,8 @@ ovl_iterator::exporting_p () const unsigned walk_module_binding (tree binding, bitmap partitions, - bool (*callback) (tree decl, WMB_Flags, void *data), + bool (*callback) (tree decl, WMB_Flags, void *data, + location_t loc), void *data) { tree current = binding; @@ -4249,6 +4261,7 @@ walk_module_binding (tree binding, bitmap partitions, if (tree type = MAYBE_STAT_TYPE (current)) { WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (STAT_TYPE_HIDDEN_P (current)) flags = WMB_Flags (flags | WMB_Hidden); if (TREE_CODE (type) == USING_DECL) @@ -4258,8 +4271,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (DECL_MODULE_EXPORT_P (type)) flags = WMB_Flags (flags | WMB_Export); + loc = DECL_SOURCE_LOCATION (type); } - count += callback (type, flags, data); + count += callback (type, flags, data, loc); decl_hidden = STAT_DECL_HIDDEN_P (current); } @@ -4270,6 +4284,7 @@ walk_module_binding (tree binding, bitmap partitions, if (!(decl_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))) { WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (decl_hidden) flags = WMB_Flags (flags | WMB_Hidden); if (iter.using_p ()) @@ -4279,8 +4294,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (iter.exporting_p ()) flags = WMB_Flags (flags | WMB_Export); + loc = iter.source_location (); } - count += callback (*iter, flags, data); + count += callback (*iter, flags, data, loc); } decl_hidden = false; } @@ -4319,13 +4335,14 @@ walk_module_binding (tree binding, bitmap partitions, WMB_Flags flags = WMB_None; if (maybe_dups) flags = WMB_Flags (flags | WMB_Dups); - count += callback (bind, flags, data); + count += callback (bind, flags, data, UNKNOWN_LOCATION); } else if (STAT_HACK_P (bind) && MODULE_BINDING_PARTITION_P (bind)) { if (tree btype = STAT_TYPE (bind)) { WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (maybe_dups) flags = WMB_Flags (flags | WMB_Dups); if (STAT_TYPE_HIDDEN_P (bind)) @@ -4337,8 +4354,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (DECL_MODULE_EXPORT_P (btype)) flags = WMB_Flags (flags | WMB_Export); + loc = DECL_SOURCE_LOCATION (btype); } - count += callback (btype, flags, data); + count += callback (btype, flags, data, loc); } bool part_hidden = STAT_DECL_HIDDEN_P (bind); for (ovl_iterator iter (MAYBE_STAT_DECL (STAT_DECL (bind))); @@ -4350,6 +4368,7 @@ walk_module_binding (tree binding, bitmap partitions, (!(part_hidden && DECL_IS_UNDECLARED_BUILTIN (*iter))); WMB_Flags flags = WMB_None; + location_t loc = UNKNOWN_LOCATION; if (maybe_dups) flags = WMB_Flags (flags | WMB_Dups); if (part_hidden) @@ -4361,8 +4380,9 @@ walk_module_binding (tree binding, bitmap partitions, flags = WMB_Flags (flags | WMB_Purview); if (iter.exporting_p ()) flags = WMB_Flags (flags | WMB_Export); + loc = iter.source_location (); } - count += callback (*iter, flags, data); + count += callback (*iter, flags, data, loc); part_hidden = false; } } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 5cf6ae6374a..8183cd50159 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -499,7 +499,8 @@ enum WMB_Flags }; extern unsigned walk_module_binding (tree binding, bitmap partitions, - bool (*)(tree decl, WMB_Flags, void *data), + bool (*)(tree decl, WMB_Flags, void *data, + location_t loc), void *data); extern tree add_imported_namespace (tree ctx, tree name, location_t, unsigned module, diff --git a/gcc/cp/ptree.cc b/gcc/cp/ptree.cc index 15e46752d01..4f7fc96cc74 100644 --- a/gcc/cp/ptree.cc +++ b/gcc/cp/ptree.cc @@ -299,6 +299,12 @@ cxx_print_xnode (FILE *file, tree node, int indent) print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4); break; case OVERLOAD: + if (location_t loc = OVL_SOURCE_LOCATION (node)) + { + expanded_location xloc = expand_location (loc); + indent_to (file, indent + 4); + fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column); + } print_node (file, "function", OVL_FUNCTION (node), indent + 4); print_node (file, "next", OVL_CHAIN (node), indent + 4); break; diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index dfd4a3a948b..21d8e0de329 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -2387,6 +2387,7 @@ ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden) OVL_PURVIEW_P (maybe_ovl) = true; if (using_or_hidden > 2) OVL_EXPORT_P (maybe_ovl) = true; + OVL_SOURCE_LOCATION (maybe_ovl) = input_location; } } else @@ -2532,6 +2533,7 @@ lookup_maybe_add (tree fns, tree lookup, bool deduping) { lookup = ovl_make (OVL_FUNCTION (fns), lookup); OVL_USING_P (lookup) = true; + OVL_SOURCE_LOCATION (lookup) = OVL_SOURCE_LOCATION (fns); } else lookup = lookup_add (OVL_FUNCTION (fns), lookup);