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)
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)
{
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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;