From: Patrick Palka <ppalka@redhat.com>
To: Nathaniel Shead <nathanieloshead@gmail.com>
Cc: gcc-patches@gcc.gnu.org, Jason Merrill <jason@redhat.com>,
Nathan Sidwell <nathan@acm.org>,
Patrick Palka <ppalka@redhat.com>
Subject: Re: [PATCH v2 1/2] c++: Standardise errors for module_may_redeclare
Date: Wed, 17 Apr 2024 11:13:16 -0400 (EDT) [thread overview]
Message-ID: <fdeaad49-fe0c-80b0-6562-d35d1dbb5459@idea> (raw)
In-Reply-To: <661cb1e4.170a0220.e8efc.335d@mx.google.com>
On Mon, 15 Apr 2024, Nathaniel Shead wrote:
> I took another look at this patch and have split it into two, one (this
> one) to standardise the error messages used and prepare
> 'module_may_redeclare' for use with temploid friends, and another
> followup patch to actually handle them correctly.
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
LGTM
>
> -- >8 --
>
> Currently different places calling 'module_may_redeclare' all emit very
> similar but slightly different error messages, and handle different
> kinds of declarations differently. This patch makes the function
> perform its own error messages so that they're all in one place, and
> prepares it for use with temploid friends (PR c++/114275).
>
> gcc/cp/ChangeLog:
>
> * cp-tree.h (module_may_redeclare): Add default parameter.
> * decl.cc (duplicate_decls): Don't emit errors for failed
> module_may_redeclare.
> (xref_tag): Likewise.
> (start_enum): Likewise.
> * semantics.cc (begin_class_definition): Likewise.
> * module.cc (module_may_redeclare): Clean up logic. Emit error
> messages on failure.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/modules/enum-12.C: Update error message.
> * g++.dg/modules/friend-5_b.C: Likewise.
> * g++.dg/modules/shadow-1_b.C: Likewise.
>
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
> gcc/cp/cp-tree.h | 2 +-
> gcc/cp/decl.cc | 28 +----
> gcc/cp/module.cc | 120 ++++++++++++++--------
> gcc/cp/semantics.cc | 6 +-
> gcc/testsuite/g++.dg/modules/enum-12.C | 2 +-
> gcc/testsuite/g++.dg/modules/friend-5_b.C | 2 +-
> gcc/testsuite/g++.dg/modules/shadow-1_b.C | 5 +-
> 7 files changed, 89 insertions(+), 76 deletions(-)
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 1dbb577a38d..faa7a0052a5 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -7401,7 +7401,7 @@ inline bool module_exporting_p ()
>
> extern module_state *get_module (tree name, module_state *parent = NULL,
> bool partition = false);
> -extern bool module_may_redeclare (tree decl);
> +extern bool module_may_redeclare (tree olddecl, tree newdecl = NULL);
>
> extern bool module_global_init_needed ();
> extern bool module_determine_import_inits ();
> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> index 65ab64885ff..aa66da4829d 100644
> --- a/gcc/cp/decl.cc
> +++ b/gcc/cp/decl.cc
> @@ -2279,18 +2279,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
> && TREE_CODE (olddecl) != NAMESPACE_DECL
> && !hiding)
> {
> - if (!module_may_redeclare (olddecl))
> - {
> - if (DECL_ARTIFICIAL (olddecl))
> - error ("declaration %qD conflicts with builtin", newdecl);
> - else
> - {
> - error ("declaration %qD conflicts with import", newdecl);
> - inform (olddecl_loc, "import declared %q#D here", olddecl);
> - }
> -
> - return error_mark_node;
> - }
> + if (!module_may_redeclare (olddecl, newdecl))
> + return error_mark_node;
>
> tree not_tmpl = STRIP_TEMPLATE (olddecl);
> if (DECL_LANG_SPECIFIC (not_tmpl)
> @@ -16620,12 +16610,7 @@ xref_tag (enum tag_types tag_code, tree name,
> {
> tree decl = TYPE_NAME (t);
> if (!module_may_redeclare (decl))
> - {
> - auto_diagnostic_group d;
> - error ("cannot declare %qD in a different module", decl);
> - inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
> - return error_mark_node;
> - }
> + return error_mark_node;
>
> tree not_tmpl = STRIP_TEMPLATE (decl);
> if (DECL_LANG_SPECIFIC (not_tmpl)
> @@ -16973,12 +16958,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
> {
> tree decl = TYPE_NAME (enumtype);
> if (!module_may_redeclare (decl))
> - {
> - auto_diagnostic_group d;
> - error ("cannot declare %qD in different module", decl);
> - inform (DECL_SOURCE_LOCATION (decl), "previously declared here");
> - enumtype = error_mark_node;
> - }
> + enumtype = error_mark_node;
> else
> set_instantiating_module (decl);
> }
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index 001430a4a8f..e2d2910ae48 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -18992,11 +18992,15 @@ get_importing_module (tree decl, bool flexible)
> return module->mod;
> }
>
> -/* Is it permissible to redeclare DECL. */
> +/* Is it permissible to redeclare OLDDECL with NEWDECL.
> +
> + If NEWDECL is NULL, assumes that OLDDECL will be redeclared using
> + the current scope's module and attachment. */
>
> bool
> -module_may_redeclare (tree decl)
> +module_may_redeclare (tree olddecl, tree newdecl)
> {
> + tree decl = olddecl;
> for (;;)
> {
> tree ctx = CP_DECL_CONTEXT (decl);
> @@ -19010,58 +19014,94 @@ module_may_redeclare (tree decl)
> decl = TYPE_NAME (ctx);
> }
>
> - tree not_tmpl = STRIP_TEMPLATE (decl);
> -
> int use_tpl = 0;
> - if (node_template_info (not_tmpl, use_tpl) && use_tpl)
> + if (node_template_info (STRIP_TEMPLATE (decl), use_tpl) && use_tpl)
> // Specializations of any kind can be redeclared anywhere.
> // FIXME: Should we be checking this in more places on the scope chain?
> return true;
>
> - if (!DECL_LANG_SPECIFIC (not_tmpl) || !DECL_MODULE_ATTACH_P (not_tmpl))
> - // Decl is attached to global module. Current scope needs to be too.
> - return !module_attach_p ();
> + module_state *old_mod = (*modules)[0];
> + module_state *new_mod = old_mod;
>
> - module_state *me = (*modules)[0];
> - module_state *them = me;
> + tree old_origin = get_originating_module_decl (decl);
> + tree old_inner = STRIP_TEMPLATE (old_origin);
> + bool olddecl_attached_p = (DECL_LANG_SPECIFIC (old_inner)
> + && DECL_MODULE_ATTACH_P (old_inner));
> + if (DECL_LANG_SPECIFIC (old_inner) && DECL_MODULE_IMPORT_P (old_inner))
> + {
> + unsigned index = import_entity_index (old_origin);
> + old_mod = import_entity_module (index);
> + }
>
> - if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_IMPORT_P (not_tmpl))
> + bool newdecl_attached_p = module_attach_p ();
> + if (newdecl)
> {
> - /* We can be given the TEMPLATE_RESULT. We want the
> - TEMPLATE_DECL. */
> - int use_tpl = -1;
> - if (tree ti = node_template_info (decl, use_tpl))
> + tree new_origin = get_originating_module_decl (newdecl);
> + tree new_inner = STRIP_TEMPLATE (new_origin);
> + newdecl_attached_p = (DECL_LANG_SPECIFIC (new_inner)
> + && DECL_MODULE_ATTACH_P (new_inner));
> + if (DECL_LANG_SPECIFIC (new_inner) && DECL_MODULE_IMPORT_P (new_inner))
> {
> - tree tmpl = TI_TEMPLATE (ti);
> - if (use_tpl == 2)
> - {
> - /* A partial specialization. Find that specialization's
> - template_decl. */
> - for (tree list = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
> - list; list = TREE_CHAIN (list))
> - if (DECL_TEMPLATE_RESULT (TREE_VALUE (list)) == decl)
> - {
> - decl = TREE_VALUE (list);
> - break;
> - }
> - }
> - else if (DECL_TEMPLATE_RESULT (tmpl) == decl)
> - decl = tmpl;
> + unsigned index = import_entity_index (new_origin);
> + new_mod = import_entity_module (index);
> }
> - unsigned index = import_entity_index (decl);
> - them = import_entity_module (index);
> }
>
> - // Decl is attached to named module. Current scope needs to be
> - // attaching to the same module.
> - if (!module_attach_p ())
> - return false;
> + /* Module attachment needs to match. */
> + if (olddecl_attached_p == newdecl_attached_p)
> + {
> + if (!olddecl_attached_p)
> + /* Both are GM entities, OK. */
> + return true;
>
> - // Both attached to named module.
> - if (me == them)
> - return true;
> + if (new_mod == old_mod
> + || (new_mod && get_primary (new_mod) == get_primary (old_mod)))
> + /* Both attached to same named module, OK. */
> + return true;
> + }
> +
> + /* Attached to different modules, error. */
> + decl = newdecl ? newdecl : olddecl;
> + location_t loc = newdecl ? DECL_SOURCE_LOCATION (newdecl) : input_location;
> + if (DECL_ARTIFICIAL (olddecl) && !DECL_IMPLICIT_TYPEDEF_P (olddecl))
> + error_at (loc, "declaration %qD conflicts with builtin", decl);
> + else if (DECL_LANG_SPECIFIC (old_inner) && DECL_MODULE_IMPORT_P (old_inner))
> + {
> + auto_diagnostic_group d;
> + if (newdecl_attached_p)
> + error_at (loc, "redeclaring %qD in module %qs conflicts with import",
> + decl, new_mod->get_flatname ());
> + else
> + error_at (loc, "redeclaring %qD in global module conflicts with import",
> + decl);
>
> - return me && get_primary (them) == get_primary (me);
> + if (olddecl_attached_p)
> + inform (DECL_SOURCE_LOCATION (olddecl),
> + "import declared attached to module %qs",
> + old_mod->get_flatname ());
> + else
> + inform (DECL_SOURCE_LOCATION (olddecl),
> + "import declared in global module");
> + }
> + else
> + {
> + auto_diagnostic_group d;
> + if (newdecl_attached_p)
> + error_at (loc, "conflicting declaration of %qD in module %qs",
> + decl, new_mod->get_flatname ());
> + else
> + error_at (loc, "conflicting declaration of %qD in global module",
> + decl);
> +
> + if (olddecl_attached_p)
> + inform (DECL_SOURCE_LOCATION (olddecl),
> + "previously declared in module %qs",
> + old_mod->get_flatname ());
> + else
> + inform (DECL_SOURCE_LOCATION (olddecl),
> + "previously declared in global module");
> + }
> + return false;
> }
>
> /* DECL is being created by this TU. Record it came from here. We
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 02c7c1bf5a4..2dde65a970b 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -3777,11 +3777,7 @@ begin_class_definition (tree t)
> if (modules_p ())
> {
> if (!module_may_redeclare (TYPE_NAME (t)))
> - {
> - error ("cannot declare %qD in a different module", TYPE_NAME (t));
> - inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)), "declared here");
> - return error_mark_node;
> - }
> + return error_mark_node;
> set_instantiating_module (TYPE_NAME (t));
> set_defining_module (TYPE_NAME (t));
> }
> diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
> index 57eeb85d92a..019c3da4218 100644
> --- a/gcc/testsuite/g++.dg/modules/enum-12.C
> +++ b/gcc/testsuite/g++.dg/modules/enum-12.C
> @@ -4,7 +4,7 @@
>
> export module foo;
> namespace std {
> - enum class align_val_t : decltype(sizeof(int)) {}; // { dg-error "different module" }
> + enum class align_val_t : decltype(sizeof(int)) {}; // { dg-error "conflicting declaration" }
> }
>
> // { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/friend-5_b.C b/gcc/testsuite/g++.dg/modules/friend-5_b.C
> index f043d7a340d..6b561265155 100644
> --- a/gcc/testsuite/g++.dg/modules/friend-5_b.C
> +++ b/gcc/testsuite/g++.dg/modules/friend-5_b.C
> @@ -4,7 +4,7 @@
> export module bar;
> import foo;
>
> -class B { // { dg-error "in a different module" }
> +class B { // { dg-error "conflicts with import" }
> B() { object.value = 42; }
> A object;
> };
> diff --git a/gcc/testsuite/g++.dg/modules/shadow-1_b.C b/gcc/testsuite/g++.dg/modules/shadow-1_b.C
> index 646381237ac..7f6a3182998 100644
> --- a/gcc/testsuite/g++.dg/modules/shadow-1_b.C
> +++ b/gcc/testsuite/g++.dg/modules/shadow-1_b.C
> @@ -1,8 +1,5 @@
> // { dg-additional-options -fmodules-ts }
> import shadow;
>
> -// unfortunately not the exact same diagnostic in both cases :(
> -
> void stat (); // { dg-error "conflicts with import" }
> -
> -struct stat {}; // { dg-error "in a different module" }
> +struct stat {}; // { dg-error "conflicts with import" }
> --
> 2.43.2
>
>
next prev parent reply other threads:[~2024-04-17 15:13 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-25 9:17 [PATCH] c++/modules: Fix instantiation of imported temploid friends [PR114275] Nathaniel Shead
2024-04-15 4:49 ` [PATCH v2 1/2] c++: Standardise errors for module_may_redeclare Nathaniel Shead
2024-04-17 15:13 ` Patrick Palka [this message]
2024-04-19 16:18 ` Nathaniel Shead
2024-04-25 19:52 ` Jason Merrill
2024-04-15 4:53 ` [PATCH v2 2/2] c++/modules: Fix instantiation of imported temploid friends [PR114275] Nathaniel Shead
2024-04-17 18:02 ` Patrick Palka
2024-04-19 2:14 ` Nathaniel Shead
2024-04-19 16:29 ` [PATCH v3 2/2] c++: " Nathaniel Shead
2024-04-27 1:16 ` Jason Merrill
2024-04-29 9:34 ` [PATCH v4 " Nathaniel Shead
2024-04-29 22:37 ` Jason Merrill
2024-05-13 11:56 ` [PATCH][14 backport] " Nathaniel Shead
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fdeaad49-fe0c-80b0-6562-d35d1dbb5459@idea \
--to=ppalka@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
--cc=nathan@acm.org \
--cc=nathanieloshead@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).