Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
-- >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 <[email protected]>
---
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));
+}
--
2.47.0