We were not correctly handling cross-module redeclarations of partial-specializations. They have their own TEMPLATE_DECL, which we need to locate. I had a FIXME there about this case. Guess it's fixed now.

        PR 99480
        gcc/cp/
        * module.cc (depset::hash::make_dependency): Propagate flags for
        partial specialization.
        (module_may_redeclare): Handle partial specialization.
        gcc/testsuite/
        * g++.dg/modules/pr99480_1.H: New.
        * g++.dg/modules/pr99480_b.H: New.

--
Nathan Sidwell
diff --git c/gcc/cp/module.cc w/gcc/cp/module.cc
index ad3b7d53451..e4da5557f9e 100644
--- c/gcc/cp/module.cc
+++ w/gcc/cp/module.cc
@@ -12444,6 +12444,11 @@ depset::hash::make_dependency (tree decl, entity_kind ek)
 
 	      *slot = redirect;
 
+	      if (DECL_LANG_SPECIFIC (decl))
+		{
+		  DECL_MODULE_IMPORT_P (partial) = DECL_MODULE_IMPORT_P (decl);
+		  DECL_MODULE_PURVIEW_P (partial) = DECL_MODULE_PURVIEW_P (decl);
+		}
 	      depset *tmpl_dep = make_dependency (partial, EK_PARTIAL);
 	      gcc_checking_assert (tmpl_dep->get_entity_kind () == EK_PARTIAL);
 
@@ -18429,13 +18434,20 @@ module_may_redeclare (tree decl)
       if (tree ti = node_template_info (decl, use_tpl))
 	{
 	  tree tmpl = TI_TEMPLATE (ti);
-	  if (DECL_TEMPLATE_RESULT (tmpl) == decl)
+	  if (use_tpl == 2)
+	    {
+	      /* A partial specialization.  Find that specialization's
+		 template_decl.  */
+	      for (tree list = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
+		   list; list = TREE_CHAIN (list))
+		if (DECL_TEMPLATE_RESULT (TREE_VALUE (list)) == decl)
+		  {
+		    decl = TREE_VALUE (list);
+		    break;
+		}
+	    }
+	  else if (DECL_TEMPLATE_RESULT (tmpl) == decl)
 	    decl = tmpl;
-	  // FIXME: What about partial specializations?  We need to
-	  // look at the specialization list in that case.  Unless our
-	  // caller's given us the right thing.  An alternative would
-	  // be to put both the template and the result into the
-	  // entity hash, but that seems expensive?
 	}
       unsigned index = import_entity_index (decl);
       them = import_entity_module (index);
diff --git c/gcc/testsuite/g++.dg/modules/pr99480_a.H w/gcc/testsuite/g++.dg/modules/pr99480_a.H
new file mode 100644
index 00000000000..8f48493c491
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99480_a.H
@@ -0,0 +1,10 @@
+// PR 99480 ICE on instantiation definition
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+template<typename _Tp>
+struct atomic;
+
+template<typename _Tp>
+struct atomic<_Tp*>;
+
+
diff --git c/gcc/testsuite/g++.dg/modules/pr99480_b.H w/gcc/testsuite/g++.dg/modules/pr99480_b.H
new file mode 100644
index 00000000000..ea8800d67b0
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99480_b.H
@@ -0,0 +1,9 @@
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+import  "pr99480_a.H";
+
+template<typename _Tp>
+struct atomic<_Tp*>
+{
+};

Reply via email to