aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-08-15 21:46:09 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2024-08-20 17:13:53 +1000
commitc310d29cac1c3a770f48ab8bb2d295ef9cc08c53 (patch)
treeb8520ac5d2b4ed5a77f13ad554714904ffe0f598 /gcc
parent80fda0ad3142c60dac0d5ef41c3e2141c9e8a521 (diff)
downloadgcc-c310d29cac1c3a770f48ab8bb2d295ef9cc08c53.zip
gcc-c310d29cac1c3a770f48ab8bb2d295ef9cc08c53.tar.gz
gcc-c310d29cac1c3a770f48ab8bb2d295ef9cc08c53.tar.bz2
c++/modules: Fix type lookup in DECL_TEMPLATE_INSTANTIATIONS [PR116364]
We need to use the DECL_TEMPLATE_INSTANTIATIONS property to find reachable specialisations from a template to ensure that any GM specialisations are properly marked as reachable. Currently the modules code uses the decl when rebuilding this property, but this is not always correct; it appears that for type specialisations we need to use the TREE_TYPE of the decl instead so that the specialisation is correctly found. This patch makes the required adjustments. PR c++/116364 gcc/cp/ChangeLog: * cp-tree.h (get_mergeable_specialization_flags): Adjust signature. * module.cc (trees_out::decl_value): Indicate whether this is a type or decl specialisation. * pt.cc (get_mergeable_specialization_flags): Match against the type of a non-decl specialisation. (add_mergeable_specialization): Use the already calculated spec instead of always adding decl to DECL_TEMPLATE_INSTANTIATIONS. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-spec-9_a.C: New test. * g++.dg/modules/tpl-spec-9_b.C: New test. * g++.dg/modules/tpl-spec-9_c.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/module.cc3
-rw-r--r--gcc/cp/pt.cc8
-rw-r--r--gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C12
-rw-r--r--gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C5
-rw-r--r--gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C5
6 files changed, 31 insertions, 5 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a53fbcb..039c707 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7672,7 +7672,8 @@ extern void walk_specializations (bool,
void *),
void *);
extern tree match_mergeable_specialization (bool is_decl, spec_entry *);
-extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec);
+extern unsigned get_mergeable_specialization_flags (bool is_decl, tree tmpl,
+ tree spec);
extern void add_mergeable_specialization (bool is_decl, spec_entry *,
tree outer, unsigned);
extern tree add_to_template_args (tree, tree);
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index f4d137b..c3218bd 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -7981,7 +7981,8 @@ trees_out::decl_value (tree decl, depset *dep)
auto *entry = reinterpret_cast <spec_entry *> (dep->deps[0]);
if (streaming_p ())
- u (get_mergeable_specialization_flags (entry->tmpl, decl));
+ u (get_mergeable_specialization_flags (mk & MK_tmpl_decl_mask,
+ entry->tmpl, decl));
tree_node (entry->tmpl);
tree_node (entry->args);
}
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 684ee0c..32d164f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31561,13 +31561,14 @@ match_mergeable_specialization (bool decl_p, spec_entry *elt)
specialization lists of TMPL. */
unsigned
-get_mergeable_specialization_flags (tree tmpl, tree decl)
+get_mergeable_specialization_flags (bool decl_p, tree tmpl, tree decl)
{
unsigned flags = 0;
+ tree spec = decl_p ? decl : TREE_TYPE (decl);
for (tree inst = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
inst; inst = TREE_CHAIN (inst))
- if (TREE_VALUE (inst) == decl)
+ if (TREE_VALUE (inst) == spec)
{
flags |= 1;
break;
@@ -31625,7 +31626,8 @@ add_mergeable_specialization (bool decl_p, spec_entry *elt, tree decl,
if (flags & 1)
DECL_TEMPLATE_INSTANTIATIONS (elt->tmpl)
- = tree_cons (elt->args, decl, DECL_TEMPLATE_INSTANTIATIONS (elt->tmpl));
+ = tree_cons (elt->args, elt->spec,
+ DECL_TEMPLATE_INSTANTIATIONS (elt->tmpl));
if (flags & 2)
{
diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C b/gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C
new file mode 100644
index 0000000..d7c02bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C
@@ -0,0 +1,12 @@
+// PR c++/116364
+// { dg-additional-options "-fmodules-ts -Wno-global-module" }
+// { dg-module-cmi foo:part }
+
+module;
+template <typename> struct S {};
+template <> struct S<int>
+ { static constexpr bool value = true; };
+export module foo:part;
+
+export template <typename T>
+ constexpr bool result = S<T>::value;
diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C b/gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C
new file mode 100644
index 0000000..f2ce5c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C
@@ -0,0 +1,5 @@
+// PR c++/116364
+// { dg-additional-options "-fmodules-ts" }
+
+export module foo;
+export import :part;
diff --git a/gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C b/gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C
new file mode 100644
index 0000000..e792245
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C
@@ -0,0 +1,5 @@
+// PR c++/116364
+// { dg-additional-options "-fmodules-ts" }
+
+import foo;
+bool x = result<int>;