On 4/10/25 5:35 PM, Nathaniel Shead wrote:
On Thu, Apr 10, 2025 at 12:19:57PM -0400, Jason Merrill wrote:
On 4/10/25 8:46 AM, Nathaniel Shead wrote:
Regression raised with my by private correspondance.
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

My change in r15-9216 broke the case where we imported an uninstantiated
defaulted function over the top of one we had already finished.  This
patch ensures that we don't error for mismatches when either function
has mismatching deferral from the other.

These changes seem to mean that importing a deferred decl can overwrite
properties of an existing non-deferred one.


Right.

To assist in understanding these errors in the future as well, I've
customised the mismatch message for different cases.  I also rephrased
the message to talk about "imported declarations" rather than "global
module declarations", since as the FIXME noted we can also get
mismatches with some declarations attached to modules.  Ideally I'd like
to revisit the way this is structured entirely but that won't be
appropriate for GCC 15.

Please split these changes into a separate commit; that patch is OK.


Thanks, I've attached the patch I'll push after regtest/bootstrap.

The following patch tested so far on x86_64-pc-linux-gnu (only
modules.exp), ok for trunk if full bootstrap+regtest succeeds?

OK.

-- >8 --

My change in r15-9216 broke the case where we imported an uninstantiated
defaulted function over the top of one we had already finished.  This
patch ensures that we don't error for mismatches in this case.

gcc/cp/ChangeLog:

        * module.cc (trees_in::is_matching_decl): Don't check for
        mismatches when importing a DECL_MAYBE_DELETED function over one
        that's already finished.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/noexcept-4_a.H: New test.
        * g++.dg/modules/noexcept-4_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
Reviewed-by: Jason Merrill <ja...@redhat.com>
---
  gcc/cp/module.cc                            |  5 ++++-
  gcc/testsuite/g++.dg/modules/noexcept-4_a.H |  6 ++++++
  gcc/testsuite/g++.dg/modules/noexcept-4_b.C | 18 ++++++++++++++++++
  3 files changed, 28 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/noexcept-4_a.H
  create mode 100644 gcc/testsuite/g++.dg/modules/noexcept-4_b.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 8efa18baff1..5ff5c462e79 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12164,7 +12164,8 @@ trees_in::is_matching_decl (tree existing, tree decl, 
bool is_typedef)
                }
            }
        }
-      else if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
+      else if (!DECL_MAYBE_DELETED (d_inner)
+              && !DEFERRED_NOEXCEPT_SPEC_P (d_spec)
               && !comp_except_specs (d_spec, e_spec, ce_type))
        {
          mismatch_msg = G_("conflicting %<noexcept%> specifier for "
@@ -12195,6 +12196,8 @@ trees_in::is_matching_decl (tree existing, tree decl, 
bool is_typedef)
        if (DECL_MAYBE_DELETED (e_inner) && !DECL_MAYBE_DELETED (d_inner)
          && DECL_DECLARED_CONSTEXPR_P (d_inner))
        DECL_DECLARED_CONSTEXPR_P (e_inner) = true;
+      else if (!DECL_MAYBE_DELETED (e_inner) && DECL_MAYBE_DELETED (d_inner))
+       /* Nothing to do.  */;
        else if (DECL_DECLARED_CONSTEXPR_P (e_inner)
               != DECL_DECLARED_CONSTEXPR_P (d_inner))
        {
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-4_a.H 
b/gcc/testsuite/g++.dg/modules/noexcept-4_a.H
new file mode 100644
index 00000000000..b888a1b93e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-4_a.H
@@ -0,0 +1,6 @@
+// { dg-additional-options "-fmodule-header -std=c++20" }
+// { dg-module-cmi {} }
+
+struct exception_ptr {
+  friend bool operator==(const exception_ptr&, const exception_ptr&) = default;
+};
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-4_b.C 
b/gcc/testsuite/g++.dg/modules/noexcept-4_b.C
new file mode 100644
index 00000000000..7cc55316c7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-4_b.C
@@ -0,0 +1,18 @@
+// { dg-additional-options "-fmodules -std=c++20" }
+
+struct exception_ptr {
+  friend bool operator==(const exception_ptr&, const exception_ptr&) = default;
+};
+
+void enqueue() {
+  exception_ptr e;
+  e == e;
+}
+
+import "noexcept-4_a.H";
+
+int main() {
+  constexpr exception_ptr e;
+  static_assert(e == e);
+  static_assert(noexcept(e == e));
+}

Reply via email to