We triggered a checking assertion because when propagating deduced
noexcept, we were updating the type of the existing TEMPLATE_DECL but
not the type of its DECL_TEMPLATE_RESULT, violating assumptions made
later on during modules streaming.
But actually there was nothing to propagate here anyway, these
declarations are identical, so this patch also fixes the condition for
checking whether we need to propagate anything. And so now I don't
think there is ever a case we should have a noexcept-spec to propagate
for a TEMPLATE_DECL, so add an assertion to validate this.
PR c++/124785
gcc/cp/ChangeLog:
* module.cc (trees_in::is_matching_decl): Narrow condition for
when noexcept propagation occurs; assert that we don't propagate
noexcept-specs for TEMPLATE_DECLs.
gcc/testsuite/ChangeLog:
* g++.dg/modules/noexcept-5.h: New test.
* g++.dg/modules/noexcept-5_a.C: New test.
* g++.dg/modules/noexcept-5_b.C: New test.
* g++.dg/modules/noexcept-5_c.C: New test.
Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
tree d_spec = TYPE_RAISES_EXCEPTIONS (d_type);
if (DECL_MAYBE_DELETED (e_inner) || DEFERRED_NOEXCEPT_SPEC_P (e_spec))
{
- if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
+ if (!(DECL_MAYBE_DELETED (d_inner)
+ || DEFERRED_NOEXCEPT_SPEC_P (d_spec))
|| (UNEVALUATED_NOEXCEPT_SPEC_P (e_spec)
&& !UNEVALUATED_NOEXCEPT_SPEC_P (d_spec)))
{
dump (dumper::MERGE)
&& dump ("Propagating instantiated noexcept to %N", existing);
+ gcc_checking_assert (existing == e_inner);
TREE_TYPE (existing) = d_type;
/* Propagate to existing clones. */
--- /dev/null
+// PR c++/124785
+template <typename T> struct Iterator {
+ constexpr friend auto operator<=>(const Iterator&, const Iterator&) = default;
+};
--- /dev/null
+// PR c++/124785
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fmodules" }
+// { dg-module-cmi M:A }
+
+export module M:A;
+#include "noexcept-5.h"
--- /dev/null
+// PR c++/124785
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fmodules" }
+// { dg-module-cmi M:B }
+
+export module M:B;
+#include "noexcept-5.h"
--- /dev/null
+// PR c++/124785
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fmodules -fdump-lang-module-alias" }
+// { dg-module-cmi M }
+
+export module M;
+export import :A;
+export import :B;
+
+// The noexcept-specifiers are equivalent, no need to merge.
+// { dg-final { scan-lang-dump-not {Propagating instantiated noexcept} module } }