auto *slot = type_specializations->find_slot (elt, INSERT);
/* We don't distinguish different constrained partial type
- specializations, so there could be duplicates. Everything else
- must be new. */
- if (!(flags & 2 && *slot))
+ specializations, so there could be duplicates. In that case we
+ must propagate TYPE_CANONICAL so that they are treated as the
+ same type. Everything else must be new. */
+ if (*slot)
+ {
+ gcc_checking_assert (flags & 2);
+ TYPE_CANONICAL (elt->spec) = TYPE_CANONICAL ((*slot)->spec);
+ }
+ else
{
- gcc_checking_assert (!*slot);
-
auto entry = ggc_alloc<spec_entry> ();
*entry = *elt;
*slot = entry;
--- /dev/null
+// PR c++/113814
+
+template <typename> struct A {};
+template <typename T> A<T*> f();
+
+template <template <typename> typename, typename> struct B;
+template <template <typename> typename TT> B<TT, int> g();
--- /dev/null
+// PR c++/113814
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+#include "partial-6.h"
+
+template <typename T>
+struct A<T*> { int a; };
+
+template <template <typename> typename TT>
+struct B<TT, int> { int b; };
--- /dev/null
+// PR c++/113814
+// { dg-additional-options "-fmodules-ts -fdump-lang-module-alias" }
+// { dg-module-cmi {} }
+
+#include "partial-6.h"
+import "partial-6_a.H";
+
+template <typename, typename = void>
+struct TestTTP;
+
+inline void test() {
+ int a = f<int>().a;
+ int b = g<TestTTP>().b;
+}
+
+// { dg-final { scan-lang-dump {Read:-[0-9]*'s partial merge key \(new\) template_decl:'::template A'} module } }
+// { dg-final { scan-lang-dump {Read:-[0-9]*'s partial merge key \(new\) template_decl:'::template B'} module } }
+
+// Don't need to write the partial specialisations
+// { dg-final { scan-lang-dump-not {Wrote declaration entity:[0-9]* template_decl:'::template A<#null#>'} module } }
+// { dg-final { scan-lang-dump-not {Wrote declaration entity:[0-9]* template_decl:'::template B<template TT,int>'} module } }
--- /dev/null
+// PR c++/113814
+// { dg-additional-options "-fmodules-ts" }
+
+import "partial-6_b.H";
+
+template <typename>
+struct TestTTP2;
+
+int main() {
+ int a = f<double>().a;
+ int b = g<TestTTP2>().b;
+}