[3/4] c++/modules: Also track module purview from deferred vtable instantiation [PR114630]

Message ID 663212e0.050a0220.566c4.2dff@mx.google.com
State New
Headers
Series c++/modules: Fix missed GMF discarding |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 fail Testing failed

Commit Message

Nathaniel Shead May 1, 2024, 10 a.m. UTC
  Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

Similarly to in the previous commit, templated virtual functions are
sometimes not instantiated until after parsing has completed.  This
means that any new declarations they instantiate are incorrectly marked
as being in the module purview, causing them to not be discarded from
the GMF.

	PR c++/114630
	PR c++/114795

gcc/cp/ChangeLog:

	* decl2.cc (mark_vtable_entries): Set module purview of deferred
	instantiations from the function decl.
	(c_parse_final_cleanups): Save and restore module_kind.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/gmf-4.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
---
 gcc/cp/decl2.cc                      | 11 +++++++++--
 gcc/testsuite/g++.dg/modules/gmf-4.C | 27 +++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/gmf-4.C
  

Comments

Patrick Palka May 1, 2024, 2:14 p.m. UTC | #1
On Wed, 1 May 2024, Nathaniel Shead wrote:

> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

LGTM

> 
> -- >8 --
> 
> Similarly to in the previous commit, templated virtual functions are
> sometimes not instantiated until after parsing has completed.  This
> means that any new declarations they instantiate are incorrectly marked
> as being in the module purview, causing them to not be discarded from
> the GMF.
> 
> 	PR c++/114630
> 	PR c++/114795
> 
> gcc/cp/ChangeLog:
> 
> 	* decl2.cc (mark_vtable_entries): Set module purview of deferred
> 	instantiations from the function decl.
> 	(c_parse_final_cleanups): Save and restore module_kind.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/modules/gmf-4.C: New test.
> 
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
>  gcc/cp/decl2.cc                      | 11 +++++++++--
>  gcc/testsuite/g++.dg/modules/gmf-4.C | 27 +++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/modules/gmf-4.C
> 
> diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
> index 806a2a4bc69..0115a6b1cc9 100644
> --- a/gcc/cp/decl2.cc
> +++ b/gcc/cp/decl2.cc
> @@ -2210,6 +2210,11 @@ mark_vtable_entries (tree decl, vec<tree> &consteval_vtables)
>           location, as we're called from c_parse_final_cleanups, which
>           takes care of that.  */
>        input_location = DECL_SOURCE_LOCATION (fn);
> +      /* Similarly, any deferred instantiations should have the same
> +	 module purview as this function.  */
> +      module_kind &= ~MK_PURVIEW;
> +      if (DECL_LANG_SPECIFIC (fn) && DECL_MODULE_PURVIEW_P (fn))
> +	module_kind |= MK_PURVIEW;
>        mark_used (fn);
>      }
>  }
> @@ -5085,6 +5090,7 @@ c_parse_final_cleanups (void)
>    tree decl;
>  
>    locus_at_end_of_parsing = input_location;
> +  unsigned module_kind_at_end_of_parsing = module_kind;
>    /* We're done parsing.  */
>    at_eof = 1;
>  
> @@ -5177,9 +5183,10 @@ c_parse_final_cleanups (void)
>  	    reconsider = true;
>  	    keyed_classes->unordered_remove (i);
>  	  }
> -      /* The input_location may have been changed during marking of
> -	 vtable entries.  */
> +      /* The input_location and module_kind may have been changed
> +	 during marking of vtable entries.  */
>        input_location = locus_at_end_of_parsing;
> +      module_kind = module_kind_at_end_of_parsing;
>  
>        /* Write out needed type info variables.  We have to be careful
>  	 looping through unemitted decls, because emit_tinfo_decl may
> diff --git a/gcc/testsuite/g++.dg/modules/gmf-4.C b/gcc/testsuite/g++.dg/modules/gmf-4.C
> new file mode 100644
> index 00000000000..c95bc782cea
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/gmf-4.C
> @@ -0,0 +1,27 @@
> +// PR c++/114630
> +// { dg-additional-options "-fmodules-ts -Wno-global-module -fdump-lang-module" }
> +// { dg-module-cmi M }
> +
> +// Deferred instantiation of GM virtual functions should not place
> +// newly discovered declarations in the module purview
> +
> +module;
> +
> +template <typename T>
> +void go() {
> +  extern T fn_decl();
> +}
> +
> +template <typename T>
> +struct S {
> +  virtual void f() {
> +    go<char>();
> +  }
> +};
> +
> +S<int> s;
> +
> +export module M;
> +
> +// The whole GMF should be discarded here
> +// { dg-final { scan-lang-dump "Wrote 0 clusters" module } }
> -- 
> 2.43.2
> 
>
  

Patch

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 806a2a4bc69..0115a6b1cc9 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2210,6 +2210,11 @@  mark_vtable_entries (tree decl, vec<tree> &consteval_vtables)
          location, as we're called from c_parse_final_cleanups, which
          takes care of that.  */
       input_location = DECL_SOURCE_LOCATION (fn);
+      /* Similarly, any deferred instantiations should have the same
+	 module purview as this function.  */
+      module_kind &= ~MK_PURVIEW;
+      if (DECL_LANG_SPECIFIC (fn) && DECL_MODULE_PURVIEW_P (fn))
+	module_kind |= MK_PURVIEW;
       mark_used (fn);
     }
 }
@@ -5085,6 +5090,7 @@  c_parse_final_cleanups (void)
   tree decl;
 
   locus_at_end_of_parsing = input_location;
+  unsigned module_kind_at_end_of_parsing = module_kind;
   /* We're done parsing.  */
   at_eof = 1;
 
@@ -5177,9 +5183,10 @@  c_parse_final_cleanups (void)
 	    reconsider = true;
 	    keyed_classes->unordered_remove (i);
 	  }
-      /* The input_location may have been changed during marking of
-	 vtable entries.  */
+      /* The input_location and module_kind may have been changed
+	 during marking of vtable entries.  */
       input_location = locus_at_end_of_parsing;
+      module_kind = module_kind_at_end_of_parsing;
 
       /* Write out needed type info variables.  We have to be careful
 	 looping through unemitted decls, because emit_tinfo_decl may
diff --git a/gcc/testsuite/g++.dg/modules/gmf-4.C b/gcc/testsuite/g++.dg/modules/gmf-4.C
new file mode 100644
index 00000000000..c95bc782cea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/gmf-4.C
@@ -0,0 +1,27 @@ 
+// PR c++/114630
+// { dg-additional-options "-fmodules-ts -Wno-global-module -fdump-lang-module" }
+// { dg-module-cmi M }
+
+// Deferred instantiation of GM virtual functions should not place
+// newly discovered declarations in the module purview
+
+module;
+
+template <typename T>
+void go() {
+  extern T fn_decl();
+}
+
+template <typename T>
+struct S {
+  virtual void f() {
+    go<char>();
+  }
+};
+
+S<int> s;
+
+export module M;
+
+// The whole GMF should be discarded here
+// { dg-final { scan-lang-dump "Wrote 0 clusters" module } }