https://gcc.gnu.org/g:f4a3ae1ef5ec951f007c4bd530f30e44945c5f0d

commit r15-9216-gf4a3ae1ef5ec951f007c4bd530f30e44945c5f0d
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Fri Apr 4 19:08:40 2025 +1100

    c++/modules: Propagate bits to DECL_MAYBE_DELETED dups [PR119462]
    
    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>
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 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(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 89deabbfee37..ff8cd86c427d 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 000000000000..00494d33d7cb
--- /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 000000000000..f26f8f0f5d3d
--- /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 000000000000..a1e98a5461aa
--- /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