aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-03-22 12:35:35 -0700
committerNathan Sidwell <nathan@acm.org>2021-03-22 12:40:33 -0700
commit2bfd081f1bce3fb7f791591e741723dce4e884ed (patch)
tree532930ceb4c3ee75d3c0c1cf0433b87d86616f59 /gcc
parent02f2dc441b1954736cc61e3f97687cd23d5586c5 (diff)
downloadgcc-2bfd081f1bce3fb7f791591e741723dce4e884ed.zip
gcc-2bfd081f1bce3fb7f791591e741723dce4e884ed.tar.gz
gcc-2bfd081f1bce3fb7f791591e741723dce4e884ed.tar.bz2
c++: Cross-module partial specialiations [PR 99480]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/module.cc24
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99480_a.H10
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99480_b.H9
3 files changed, 37 insertions, 6 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ad3b7d5..e4da555 100644
--- a/gcc/cp/module.cc
+++ b/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 a/gcc/testsuite/g++.dg/modules/pr99480_a.H b/gcc/testsuite/g++.dg/modules/pr99480_a.H
new file mode 100644
index 0000000..8f48493
--- /dev/null
+++ b/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 a/gcc/testsuite/g++.dg/modules/pr99480_b.H b/gcc/testsuite/g++.dg/modules/pr99480_b.H
new file mode 100644
index 0000000..ea8800d
--- /dev/null
+++ b/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*>
+{
+};