diff mbox series

c++/modules: Fix type lookup in DECL_TEMPLATE_INSTANTIATIONS [PR116364]

Message ID 66bdecd0.620a0220.32f817.27ab@mx.google.com
State New
Headers show
Series c++/modules: Fix type lookup in DECL_TEMPLATE_INSTANTIATIONS [PR116364] | expand

Commit Message

Nathaniel Shead Aug. 15, 2024, 11:55 a.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

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>
---
 gcc/cp/cp-tree.h                            |  3 ++-
 gcc/cp/module.cc                            |  3 ++-
 gcc/cp/pt.cc                                |  8 +++++---
 gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C | 12 ++++++++++++
 gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C |  5 +++++
 gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C |  5 +++++
 6 files changed, 31 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C
 create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C

Comments

Jason Merrill Aug. 20, 2024, 12:29 a.m. UTC | #1
On 8/15/24 7:55 AM, Nathaniel Shead wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

OK.

> -- >8 --
> 
> 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>
> ---
>   gcc/cp/cp-tree.h                            |  3 ++-
>   gcc/cp/module.cc                            |  3 ++-
>   gcc/cp/pt.cc                                |  8 +++++---
>   gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C | 12 ++++++++++++
>   gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C |  5 +++++
>   gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C |  5 +++++
>   6 files changed, 31 insertions(+), 5 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-9_a.C
>   create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-9_b.C
>   create mode 100644 gcc/testsuite/g++.dg/modules/tpl-spec-9_c.C
> 
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index a53fbcb43ec..039c70710a2 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 f4d137b13a1..c3218bd5caf 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 8725a5eeb3f..1c531f456be 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -31559,13 +31559,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;
> @@ -31623,7 +31624,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 00000000000..d7c02bb279d
> --- /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 00000000000..f2ce5c2e90b
> --- /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 00000000000..e79224561ca
> --- /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>;
diff mbox series

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a53fbcb43ec..039c70710a2 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 f4d137b13a1..c3218bd5caf 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 8725a5eeb3f..1c531f456be 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31559,13 +31559,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;
@@ -31623,7 +31624,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 00000000000..d7c02bb279d
--- /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 00000000000..f2ce5c2e90b
--- /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 00000000000..e79224561ca
--- /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>;