On 4/4/25 4:14 AM, Nathaniel Shead wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

OK.

-- >8 --

In the linked PR, we're importing over a DECL_MAYBE_DELETED decl with a
decl that has already been instantiated.  This patch ensures that the
needed bits are propagated across and that DECL_MAYBE_DELETED is cleared
from the existing decl, so that later synthesize_method doesn't crash
due to a definition unexpectedly already existing.

        PR c++/119462

gcc/cp/ChangeLog:

        * module.cc (trees_in::is_matching_decl): Propagate exception
        spec and constexpr to DECL_MAYBE_DELETED; clear if appropriate.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/noexcept-3_a.C: New test.
        * g++.dg/modules/noexcept-3_b.C: New test.
        * g++.dg/modules/noexcept-3_c.C: New test.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
  gcc/cp/module.cc                            | 16 +++++++++++++++-
  gcc/testsuite/g++.dg/modules/noexcept-3_a.C | 14 ++++++++++++++
  gcc/testsuite/g++.dg/modules/noexcept-3_b.C | 12 ++++++++++++
  gcc/testsuite/g++.dg/modules/noexcept-3_c.C | 11 +++++++++++
  4 files changed, 52 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/noexcept-3_a.C
  create mode 100644 gcc/testsuite/g++.dg/modules/noexcept-3_b.C
  create mode 100644 gcc/testsuite/g++.dg/modules/noexcept-3_c.C

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ce22b2ece3f..0fc71182665 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12122,7 +12122,7 @@ trees_in::is_matching_decl (tree existing, tree decl, 
bool is_typedef)
         instantiate it in the middle of loading.   */
        tree e_spec = TYPE_RAISES_EXCEPTIONS (e_type);
        tree d_spec = TYPE_RAISES_EXCEPTIONS (d_type);
-      if (DEFERRED_NOEXCEPT_SPEC_P (e_spec))
+      if (DECL_MAYBE_DELETED (e_inner) || DEFERRED_NOEXCEPT_SPEC_P (e_spec))
        {
          if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
              || (UNEVALUATED_NOEXCEPT_SPEC_P (e_spec)
@@ -12161,6 +12161,20 @@ trees_in::is_matching_decl (tree existing, tree decl, 
bool is_typedef)
        else if (type_uses_auto (d_ret)
               && !same_type_p (TREE_TYPE (d_type), TREE_TYPE (e_type)))
        goto mismatch;
+
+      /* Similarly if EXISTING has undeduced constexpr, but DECL's
+        is already deduced.  */
+      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_DECLARED_CONSTEXPR_P (e_inner)
+              != DECL_DECLARED_CONSTEXPR_P (d_inner))
+       goto mismatch;
+
+      /* Don't synthesize a defaulted function if we're importing one
+        we've already determined.  */
+      if (!DECL_MAYBE_DELETED (d_inner))
+       DECL_MAYBE_DELETED (e_inner) = false;
      }
    else if (is_typedef)
      {
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-3_a.C 
b/gcc/testsuite/g++.dg/modules/noexcept-3_a.C
new file mode 100644
index 00000000000..00494d33d7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-3_a.C
@@ -0,0 +1,14 @@
+// PR c++/119462
+// { dg-additional-options "-fmodules -std=c++20 -Wno-global-module" }
+// { dg-module-cmi M:part }
+
+module;
+struct exception_ptr {
+  // implicitly noexcept and constexpr
+  friend bool operator==(const exception_ptr&, const exception_ptr&) = default;
+};
+export module M:part;
+export template <typename = int> void enqueue() {
+  exception_ptr e;
+  e == e;
+}
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-3_b.C 
b/gcc/testsuite/g++.dg/modules/noexcept-3_b.C
new file mode 100644
index 00000000000..f26f8f0f5d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-3_b.C
@@ -0,0 +1,12 @@
+// PR c++/119462
+// { dg-additional-options "-fmodules -std=c++20 -Wno-global-module" }
+// { dg-module-cmi M }
+
+module;
+struct exception_ptr {
+  // implicitly noexcept and constexpr, but this isn't known yet
+  friend bool operator==(const exception_ptr&, const exception_ptr&) = default;
+};
+export module M;
+export import :part;
+export using ::exception_ptr;
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-3_c.C 
b/gcc/testsuite/g++.dg/modules/noexcept-3_c.C
new file mode 100644
index 00000000000..a1e98a5461a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-3_c.C
@@ -0,0 +1,11 @@
+// PR c++/119462
+// { dg-additional-options "-fmodules -std=c++20" }
+
+import M;
+int main() {
+  enqueue();
+
+  constexpr exception_ptr e;
+  static_assert(e == e);
+  static_assert(noexcept(e == e));
+}

Reply via email to