c++: Cross-module partial specialiations [PR 99480]
authorNathan Sidwell <nathan@acm.org>
Mon, 22 Mar 2021 19:35:35 +0000 (12:35 -0700)
committerNathan Sidwell <nathan@acm.org>
Mon, 22 Mar 2021 19:40:33 +0000 (12:40 -0700)
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 c++/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_a.H: New.
* g++.dg/modules/pr99480_b.H: New.

gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/pr99480_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/pr99480_b.H [new file with mode: 0644]

index ad3b7d5..e4da555 100644 (file)
@@ -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 a/gcc/testsuite/g++.dg/modules/pr99480_a.H b/gcc/testsuite/g++.dg/modules/pr99480_a.H
new file mode 100644 (file)
index 0000000..8f48493
--- /dev/null
@@ -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 a/gcc/testsuite/g++.dg/modules/pr99480_b.H b/gcc/testsuite/g++.dg/modules/pr99480_b.H
new file mode 100644 (file)
index 0000000..ea8800d
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+import  "pr99480_a.H";
+
+template<typename _Tp>
+struct atomic<_Tp*>
+{
+};