diff mbox series

[v2] c++/modules: Remove unnecessary errors when not writing compiled module

Message ID 66c43f7b.170a0220.232602.bc15@mx.google.com
State New
Headers show
Series [v2] c++/modules: Remove unnecessary errors when not writing compiled module | expand

Commit Message

Nathaniel Shead Aug. 20, 2024, 7:02 a.m. UTC
On Mon, Aug 19, 2024 at 12:55:22PM -0400, Jason Merrill wrote:
> On 8/18/24 8:11 AM, Nathaniel Shead wrote:
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
> > 
> > Or should we even just remove the warning entirely?  I'm not sure it
> > really adds all that much, since it's usual AFAICT for errors to prevent
> > the intended outputs from being generated.
> 
> Agreed, removing it seems fine.
> 

OK thanks, here's an updated patch which removes this warning in most
cases.  Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

It was pointed out to me that the current error referencing an internal
linkage entity reads almost like an ICE message, with the message
finishing with the unhelpful:

m.cpp:1:8: error: failed to write compiled module: Bad file data
    1 | export module M;
      |        ^~~~~~

Similarly, whenever we decide not to emit a module CMI due to other
errors we currently emit the following message:

m.cpp:1:8: warning: not writing module ‘M’ due to errors
    1 | export module M;
      |        ^~~~~~

Neither of these messages really add anything useful; users already
understand that when an error is reported then the normal outputs will
not be created, so these messages are just noise.

There is one case we still need this latter message, however; when an
error in a template has been silenced with '-Wno-template-body' we still
don't want to write a module CMI, so emit an error now instead.

This patch also removes a number of dg-prune-output directives in the
testsuite that are no longer needed with this change.

gcc/cp/ChangeLog:

	* module.cc (module_state::write_begin): Return a boolean to
	indicate errors rather than just doing set_error().
	(finish_module_processing): Prevent emission of unnecessary
	errors; only indicate module writing occurred if write_begin
	succeeds.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/export-1.C: Remove message.
	* g++.dg/modules/internal-1.C: Remove message.
	* g++.dg/modules/ambig-2_b.C: Remove unnecessary pruning.
	* g++.dg/modules/atom-decl-2.C: Likewise.
	* g++.dg/modules/atom-pragma-3.C: Likewise.
	* g++.dg/modules/atom-preamble-2_f.C: Likewise.
	* g++.dg/modules/block-decl-2.C: Likewise.
	* g++.dg/modules/dir-only-4.C: Likewise.
	* g++.dg/modules/enum-12.C: Likewise.
	* g++.dg/modules/exp-xlate-1_b.C: Likewise.
	* g++.dg/modules/export-3.C: Likewise.
	* g++.dg/modules/friend-3.C: Likewise.
	* g++.dg/modules/friend-5_b.C: Likewise.
	* g++.dg/modules/inc-xlate-1_e.C: Likewise.
	* g++.dg/modules/linkage-2.C: Likewise.
	* g++.dg/modules/local-extern-1.C: Likewise.
	* g++.dg/modules/main-1.C: Likewise.
	* g++.dg/modules/map-2.C: Likewise.
	* g++.dg/modules/mod-decl-1.C: Likewise.
	* g++.dg/modules/mod-decl-3.C: Likewise.
	* g++.dg/modules/pr99174.H: Likewise.
	* g++.dg/modules/pr99468.H: Likewise.
	* g++.dg/modules/token-1.C: Likewise.
	* g++.dg/modules/token-3.C: Likewise.
	* g++.dg/modules/token-4.C: Likewise.
	* g++.dg/modules/token-5.C: Likewise.
	* g++.dg/modules/using-10.C: Likewise.
	* g++.dg/modules/using-12.C: Likewise.
	* g++.dg/modules/using-3.C: Likewise.
	* g++.dg/modules/using-9.C: Likewise.
	* g++.dg/modules/using-enum-2.C: Likewise.
	* g++.dg/modules/permissive-error-1.C: New test.
	* g++.dg/modules/permissive-error-2.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
---
 gcc/cp/module.cc                              | 42 +++++++++++--------
 gcc/testsuite/g++.dg/modules/ambig-2_b.C      |  2 -
 gcc/testsuite/g++.dg/modules/atom-decl-2.C    |  2 -
 gcc/testsuite/g++.dg/modules/atom-pragma-3.C  |  2 -
 .../g++.dg/modules/atom-preamble-2_f.C        |  1 -
 gcc/testsuite/g++.dg/modules/block-decl-2.C   |  2 -
 gcc/testsuite/g++.dg/modules/dir-only-4.C     |  1 -
 gcc/testsuite/g++.dg/modules/enum-12.C        |  2 -
 gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C  |  1 -
 gcc/testsuite/g++.dg/modules/export-1.C       |  2 -
 gcc/testsuite/g++.dg/modules/export-3.C       |  2 -
 gcc/testsuite/g++.dg/modules/friend-3.C       |  1 -
 gcc/testsuite/g++.dg/modules/friend-5_b.C     |  1 -
 gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C  |  2 -
 gcc/testsuite/g++.dg/modules/internal-1.C     |  2 +-
 gcc/testsuite/g++.dg/modules/linkage-2.C      |  2 -
 gcc/testsuite/g++.dg/modules/local-extern-1.C |  3 --
 gcc/testsuite/g++.dg/modules/main-1.C         |  1 -
 gcc/testsuite/g++.dg/modules/map-2.C          |  2 -
 gcc/testsuite/g++.dg/modules/mod-decl-1.C     |  2 -
 gcc/testsuite/g++.dg/modules/mod-decl-3.C     |  2 -
 .../g++.dg/modules/permissive-error-1.C       | 10 +++++
 .../g++.dg/modules/permissive-error-2.C       | 11 +++++
 gcc/testsuite/g++.dg/modules/pr99174.H        |  2 -
 gcc/testsuite/g++.dg/modules/pr99468.H        |  1 -
 gcc/testsuite/g++.dg/modules/token-1.C        |  1 -
 gcc/testsuite/g++.dg/modules/token-3.C        |  1 -
 gcc/testsuite/g++.dg/modules/token-4.C        |  1 -
 gcc/testsuite/g++.dg/modules/token-5.C        |  1 -
 gcc/testsuite/g++.dg/modules/using-10.C       |  2 -
 gcc/testsuite/g++.dg/modules/using-12.C       |  2 -
 gcc/testsuite/g++.dg/modules/using-3.C        |  2 -
 gcc/testsuite/g++.dg/modules/using-9.C        |  2 -
 gcc/testsuite/g++.dg/modules/using-enum-2.C   |  2 -
 34 files changed, 47 insertions(+), 68 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/permissive-error-1.C
 create mode 100644 gcc/testsuite/g++.dg/modules/permissive-error-2.C

Comments

Jason Merrill Aug. 20, 2024, 3:26 p.m. UTC | #1
On 8/20/24 3:02 AM, Nathaniel Shead wrote:
> On Mon, Aug 19, 2024 at 12:55:22PM -0400, Jason Merrill wrote:
>> On 8/18/24 8:11 AM, Nathaniel Shead wrote:
>>> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?
>>>
>>> Or should we even just remove the warning entirely?  I'm not sure it
>>> really adds all that much, since it's usual AFAICT for errors to prevent
>>> the intended outputs from being generated.
>>
>> Agreed, removing it seems fine.
>>
> 
> OK thanks, here's an updated patch which removes this warning in most
> cases.  Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

OK.

> -- >8 --
> 
> It was pointed out to me that the current error referencing an internal
> linkage entity reads almost like an ICE message, with the message
> finishing with the unhelpful:
> 
> m.cpp:1:8: error: failed to write compiled module: Bad file data
>      1 | export module M;
>        |        ^~~~~~
> 
> Similarly, whenever we decide not to emit a module CMI due to other
> errors we currently emit the following message:
> 
> m.cpp:1:8: warning: not writing module ‘M’ due to errors
>      1 | export module M;
>        |        ^~~~~~
> 
> Neither of these messages really add anything useful; users already
> understand that when an error is reported then the normal outputs will
> not be created, so these messages are just noise.
> 
> There is one case we still need this latter message, however; when an
> error in a template has been silenced with '-Wno-template-body' we still
> don't want to write a module CMI, so emit an error now instead.
> 
> This patch also removes a number of dg-prune-output directives in the
> testsuite that are no longer needed with this change.
> 
> gcc/cp/ChangeLog:
> 
> 	* module.cc (module_state::write_begin): Return a boolean to
> 	indicate errors rather than just doing set_error().
> 	(finish_module_processing): Prevent emission of unnecessary
> 	errors; only indicate module writing occurred if write_begin
> 	succeeds.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/modules/export-1.C: Remove message.
> 	* g++.dg/modules/internal-1.C: Remove message.
> 	* g++.dg/modules/ambig-2_b.C: Remove unnecessary pruning.
> 	* g++.dg/modules/atom-decl-2.C: Likewise.
> 	* g++.dg/modules/atom-pragma-3.C: Likewise.
> 	* g++.dg/modules/atom-preamble-2_f.C: Likewise.
> 	* g++.dg/modules/block-decl-2.C: Likewise.
> 	* g++.dg/modules/dir-only-4.C: Likewise.
> 	* g++.dg/modules/enum-12.C: Likewise.
> 	* g++.dg/modules/exp-xlate-1_b.C: Likewise.
> 	* g++.dg/modules/export-3.C: Likewise.
> 	* g++.dg/modules/friend-3.C: Likewise.
> 	* g++.dg/modules/friend-5_b.C: Likewise.
> 	* g++.dg/modules/inc-xlate-1_e.C: Likewise.
> 	* g++.dg/modules/linkage-2.C: Likewise.
> 	* g++.dg/modules/local-extern-1.C: Likewise.
> 	* g++.dg/modules/main-1.C: Likewise.
> 	* g++.dg/modules/map-2.C: Likewise.
> 	* g++.dg/modules/mod-decl-1.C: Likewise.
> 	* g++.dg/modules/mod-decl-3.C: Likewise.
> 	* g++.dg/modules/pr99174.H: Likewise.
> 	* g++.dg/modules/pr99468.H: Likewise.
> 	* g++.dg/modules/token-1.C: Likewise.
> 	* g++.dg/modules/token-3.C: Likewise.
> 	* g++.dg/modules/token-4.C: Likewise.
> 	* g++.dg/modules/token-5.C: Likewise.
> 	* g++.dg/modules/using-10.C: Likewise.
> 	* g++.dg/modules/using-12.C: Likewise.
> 	* g++.dg/modules/using-3.C: Likewise.
> 	* g++.dg/modules/using-9.C: Likewise.
> 	* g++.dg/modules/using-enum-2.C: Likewise.
> 	* g++.dg/modules/permissive-error-1.C: New test.
> 	* g++.dg/modules/permissive-error-2.C: New test.
> 
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> Reviewed-by: Jason Merrill <jason@redhat.com>
> ---
>   gcc/cp/module.cc                              | 42 +++++++++++--------
>   gcc/testsuite/g++.dg/modules/ambig-2_b.C      |  2 -
>   gcc/testsuite/g++.dg/modules/atom-decl-2.C    |  2 -
>   gcc/testsuite/g++.dg/modules/atom-pragma-3.C  |  2 -
>   .../g++.dg/modules/atom-preamble-2_f.C        |  1 -
>   gcc/testsuite/g++.dg/modules/block-decl-2.C   |  2 -
>   gcc/testsuite/g++.dg/modules/dir-only-4.C     |  1 -
>   gcc/testsuite/g++.dg/modules/enum-12.C        |  2 -
>   gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C  |  1 -
>   gcc/testsuite/g++.dg/modules/export-1.C       |  2 -
>   gcc/testsuite/g++.dg/modules/export-3.C       |  2 -
>   gcc/testsuite/g++.dg/modules/friend-3.C       |  1 -
>   gcc/testsuite/g++.dg/modules/friend-5_b.C     |  1 -
>   gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C  |  2 -
>   gcc/testsuite/g++.dg/modules/internal-1.C     |  2 +-
>   gcc/testsuite/g++.dg/modules/linkage-2.C      |  2 -
>   gcc/testsuite/g++.dg/modules/local-extern-1.C |  3 --
>   gcc/testsuite/g++.dg/modules/main-1.C         |  1 -
>   gcc/testsuite/g++.dg/modules/map-2.C          |  2 -
>   gcc/testsuite/g++.dg/modules/mod-decl-1.C     |  2 -
>   gcc/testsuite/g++.dg/modules/mod-decl-3.C     |  2 -
>   .../g++.dg/modules/permissive-error-1.C       | 10 +++++
>   .../g++.dg/modules/permissive-error-2.C       | 11 +++++
>   gcc/testsuite/g++.dg/modules/pr99174.H        |  2 -
>   gcc/testsuite/g++.dg/modules/pr99468.H        |  1 -
>   gcc/testsuite/g++.dg/modules/token-1.C        |  1 -
>   gcc/testsuite/g++.dg/modules/token-3.C        |  1 -
>   gcc/testsuite/g++.dg/modules/token-4.C        |  1 -
>   gcc/testsuite/g++.dg/modules/token-5.C        |  1 -
>   gcc/testsuite/g++.dg/modules/using-10.C       |  2 -
>   gcc/testsuite/g++.dg/modules/using-12.C       |  2 -
>   gcc/testsuite/g++.dg/modules/using-3.C        |  2 -
>   gcc/testsuite/g++.dg/modules/using-9.C        |  2 -
>   gcc/testsuite/g++.dg/modules/using-enum-2.C   |  2 -
>   34 files changed, 47 insertions(+), 68 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/modules/permissive-error-1.C
>   create mode 100644 gcc/testsuite/g++.dg/modules/permissive-error-2.C
> 
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index 7c42aea05ee..07477d33955 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -3681,7 +3681,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state {
>   
>    public:
>     /* Read and write module.  */
> -  void write_begin (elf_out *to, cpp_reader *,
> +  bool write_begin (elf_out *to, cpp_reader *,
>   		    module_state_config &, unsigned &crc);
>     void write_end (elf_out *to, cpp_reader *,
>   		  module_state_config &, unsigned &crc);
> @@ -18317,7 +18317,7 @@ ool_cmp (const void *a_, const void *b_)
>        MOD_SNAME_PFX.cfg      : config data
>   */
>   
> -void
> +bool
>   module_state::write_begin (elf_out *to, cpp_reader *reader,
>   			   module_state_config &config, unsigned &crc)
>   {
> @@ -18395,10 +18395,7 @@ module_state::write_begin (elf_out *to, cpp_reader *reader,
>     table.find_dependencies (this);
>   
>     if (!table.finalize_dependencies ())
> -    {
> -      to->set_error ();
> -      return;
> -    }
> +    return false;
>   
>   #if CHECKING_P
>     /* We're done verifying at-most once reading, reset to verify
> @@ -18595,6 +18592,8 @@ module_state::write_begin (elf_out *to, cpp_reader *reader,
>     // so-controlled.
>     if (false)
>       write_env (to);
> +
> +  return true;
>   }
>   
>   // Finish module writing after we've emitted all dynamic initializers.
> @@ -20847,20 +20846,29 @@ finish_module_processing (cpp_reader *reader)
>   
>         cookie = new module_processing_cookie (cmi_name, tmp_name, fd, e);
>   
> -      if (errorcount
> -	  /* Don't write the module if it contains an erroneous template.  */
> -	  || (erroneous_templates
> -	      && !erroneous_templates->is_empty ()))
> -	warning_at (state->loc, 0, "not writing module %qs due to errors",
> -		    state->get_flatname ());
> +      if (errorcount)
> +	/* Don't write the module if we have reported errors.  */;
> +      else if (erroneous_templates
> +	       && !erroneous_templates->is_empty ())
> +	{
> +	  /* Don't write the module if it contains an erroneous template.
> +	     Also emit notes about where errors occurred in case
> +	     -Wno-template-body was passed.  */
> +	  auto_diagnostic_group d;
> +	  error_at (state->loc, "not writing module %qs due to errors "
> +		    "in template bodies", state->get_flatname ());
> +	  if (!warn_template_body)
> +	    inform (state->loc, "enable %<-Wtemplate-body%> for more details");
> +	  for (auto e : *erroneous_templates)
> +	    inform (e.second, "first error in %qD appeared here", e.first);
> +	}
>         else if (cookie->out.begin ())
>   	{
> -	  cookie->began = true;
> -	  auto loc = input_location;
>   	  /* So crashes finger-point the module decl.  */
> -	  input_location = state->loc;
> -	  state->write_begin (&cookie->out, reader, cookie->config, cookie->crc);
> -	  input_location = loc;
> +	  iloc_sentinel ils = state->loc;
> +	  if (state->write_begin (&cookie->out, reader, cookie->config,
> +				  cookie->crc))
> +	    cookie->began = true;
>   	}
>   
>         dump.pop (n);
> diff --git a/gcc/testsuite/g++.dg/modules/ambig-2_b.C b/gcc/testsuite/g++.dg/modules/ambig-2_b.C
> index b94416aabbf..859cf14ac07 100644
> --- a/gcc/testsuite/g++.dg/modules/ambig-2_b.C
> +++ b/gcc/testsuite/g++.dg/modules/ambig-2_b.C
> @@ -6,5 +6,3 @@ import A;
>   
>   extern "C++" int foo ();
>   extern "C++" int bar ();  // { dg-error "ambiguating new declaration" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/atom-decl-2.C b/gcc/testsuite/g++.dg/modules/atom-decl-2.C
> index b463dc8e214..43120152b45 100644
> --- a/gcc/testsuite/g++.dg/modules/atom-decl-2.C
> +++ b/gcc/testsuite/g++.dg/modules/atom-decl-2.C
> @@ -2,5 +2,3 @@
>   export module thing;
>   int i;
>   import baz; // { dg-error "must be contiguous" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/atom-pragma-3.C b/gcc/testsuite/g++.dg/modules/atom-pragma-3.C
> index b95b2c8ad75..f2cadf02f2f 100644
> --- a/gcc/testsuite/g++.dg/modules/atom-pragma-3.C
> +++ b/gcc/testsuite/g++.dg/modules/atom-pragma-3.C
> @@ -8,5 +8,3 @@ export module foo;
>   import baz; // { dg-error "must be contiguous" }
>   
>   int i;
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C b/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C
> index 28e54b808b2..42b84af651c 100644
> --- a/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C
> +++ b/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C
> @@ -7,4 +7,3 @@ import kevin; // { dg-error "not be from header" }
>   # 8 "" 2
>   
>   import kevin; // ok
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/block-decl-2.C b/gcc/testsuite/g++.dg/modules/block-decl-2.C
> index 974e26f9b7a..d491a18dfb1 100644
> --- a/gcc/testsuite/g++.dg/modules/block-decl-2.C
> +++ b/gcc/testsuite/g++.dg/modules/block-decl-2.C
> @@ -17,5 +17,3 @@ export extern "C++" auto foo() {
>     };
>     return X{};
>   }
> -
> -// { dg-prune-output "failed to write compiled module" }
> diff --git a/gcc/testsuite/g++.dg/modules/dir-only-4.C b/gcc/testsuite/g++.dg/modules/dir-only-4.C
> index 80d6461e81f..9cb0587c0aa 100644
> --- a/gcc/testsuite/g++.dg/modules/dir-only-4.C
> +++ b/gcc/testsuite/g++.dg/modules/dir-only-4.C
> @@ -7,4 +7,3 @@ export module foo;
>   class import {};
>   
>   import x; // { dg-error "post-module-declaration" }
> - // { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
> index cf8f445e076..3f29c52d59d 100644
> --- a/gcc/testsuite/g++.dg/modules/enum-12.C
> +++ b/gcc/testsuite/g++.dg/modules/enum-12.C
> @@ -6,5 +6,3 @@ export module foo;
>   namespace std {
>     enum class align_val_t : decltype(sizeof(int)) {};  // { dg-error "in module .foo. conflicts with builtin" }
>   }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C b/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C
> index 3295a6af050..736e891d1c7 100644
> --- a/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C
> +++ b/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C
> @@ -4,4 +4,3 @@ export module evil;
>   
>   export // { dg-error "not part of following" }
>   #include "exp-xlate-1_a.H" // { dg-error "must be contiguous" }
> -// { dg-prune-output {not writing module} }
> diff --git a/gcc/testsuite/g++.dg/modules/export-1.C b/gcc/testsuite/g++.dg/modules/export-1.C
> index 598814370ec..071f5ca2f35 100644
> --- a/gcc/testsuite/g++.dg/modules/export-1.C
> +++ b/gcc/testsuite/g++.dg/modules/export-1.C
> @@ -24,5 +24,3 @@ export class A; // { dg-error "conflicting exporting for declaration" }
>   
>   template <typename T> struct B;
>   export template <typename T> struct B {};  // { dg-error "conflicting exporting for declaration" }
> -
> -// { dg-warning "due to errors" "" { target *-*-* } 0 }
> diff --git a/gcc/testsuite/g++.dg/modules/export-3.C b/gcc/testsuite/g++.dg/modules/export-3.C
> index 76765fd2b2f..6af314b9519 100644
> --- a/gcc/testsuite/g++.dg/modules/export-3.C
> +++ b/gcc/testsuite/g++.dg/modules/export-3.C
> @@ -26,5 +26,3 @@ namespace {
>   }
>   
>   export namespace {}  // { dg-error "internal linkage" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/friend-3.C b/gcc/testsuite/g++.dg/modules/friend-3.C
> index 48320eba46a..cf0bbb7de5e 100644
> --- a/gcc/testsuite/g++.dg/modules/friend-3.C
> +++ b/gcc/testsuite/g++.dg/modules/friend-3.C
> @@ -31,4 +31,3 @@ export void quux (); // { dg-error "conflicting export" }
>   void toto (); // not exported
>   
>   }
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/friend-5_b.C b/gcc/testsuite/g++.dg/modules/friend-5_b.C
> index 6b561265155..b362cf82547 100644
> --- a/gcc/testsuite/g++.dg/modules/friend-5_b.C
> +++ b/gcc/testsuite/g++.dg/modules/friend-5_b.C
> @@ -8,4 +8,3 @@ class B { // { dg-error "conflicts with import" }
>     B() { object.value = 42; }
>     A object;
>   };
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C b/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C
> index f33c464bee9..338c017c9b9 100644
> --- a/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C
> +++ b/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C
> @@ -1,5 +1,3 @@
>   // { dg-additional-options "-fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ -t\\ [srcdir]/inc-xlate-1.map" }
>   export module bad;
>   #include "inc-xlate-1_a.H"  // { dg-error "not be include-translated" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/internal-1.C b/gcc/testsuite/g++.dg/modules/internal-1.C
> index 45d3bf06f28..9f7299a5fc7 100644
> --- a/gcc/testsuite/g++.dg/modules/internal-1.C
> +++ b/gcc/testsuite/g++.dg/modules/internal-1.C
> @@ -1,6 +1,6 @@
>   // { dg-additional-options "-fmodules-ts" }
>   
> -export module frob; // { dg-error "failed to write" }
> +export module frob;
>   // { dg-module-cmi !frob }
>   
>   namespace {
> diff --git a/gcc/testsuite/g++.dg/modules/linkage-2.C b/gcc/testsuite/g++.dg/modules/linkage-2.C
> index d913d6a30fc..4b20411572c 100644
> --- a/gcc/testsuite/g++.dg/modules/linkage-2.C
> +++ b/gcc/testsuite/g++.dg/modules/linkage-2.C
> @@ -28,5 +28,3 @@ export void use() {
>   // here is an exposure of this type, so this should be an error; we don't yet
>   // implement this checking however.
>   struct {} s;  // { dg-error "TU-local" "" { xfail *-*-* } }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/local-extern-1.C b/gcc/testsuite/g++.dg/modules/local-extern-1.C
> index 7b016053d36..3e10c67d132 100644
> --- a/gcc/testsuite/g++.dg/modules/local-extern-1.C
> +++ b/gcc/testsuite/g++.dg/modules/local-extern-1.C
> @@ -15,6 +15,3 @@ inline void dob ()
>   {
>     extern int bob; // { dg-error "block-scope extern" }
>   }
> -
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/main-1.C b/gcc/testsuite/g++.dg/modules/main-1.C
> index 0d79edddb75..42929778481 100644
> --- a/gcc/testsuite/g++.dg/modules/main-1.C
> +++ b/gcc/testsuite/g++.dg/modules/main-1.C
> @@ -1,5 +1,4 @@
>   // { dg-additional-options "-fmodules-ts" }
> -// { dg-prune-output "not writing module" }
>   
>   export module M;
>   int main() {}  // { dg-error "attach" }
> diff --git a/gcc/testsuite/g++.dg/modules/map-2.C b/gcc/testsuite/g++.dg/modules/map-2.C
> index dceb1834196..94d3f7a1a41 100644
> --- a/gcc/testsuite/g++.dg/modules/map-2.C
> +++ b/gcc/testsuite/g++.dg/modules/map-2.C
> @@ -7,5 +7,3 @@
>   export module foo;
>   // { dg-error "Interface: no such module" "" { target *-*-* } .-1 }
>   // { dg-error "failed reading mapper" "" { target *-*-* } 0 }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/mod-decl-1.C b/gcc/testsuite/g++.dg/modules/mod-decl-1.C
> index df398b3ef50..ac7bb84699a 100644
> --- a/gcc/testsuite/g++.dg/modules/mod-decl-1.C
> +++ b/gcc/testsuite/g++.dg/modules/mod-decl-1.C
> @@ -27,5 +27,3 @@ void Bink ()
>   
>   module a.; // { dg-error "only permitted as" }
>   
> -// { dg-prune-output "not writing module" }
> -
> diff --git a/gcc/testsuite/g++.dg/modules/mod-decl-3.C b/gcc/testsuite/g++.dg/modules/mod-decl-3.C
> index 16fa5a85a56..23ba7f13957 100644
> --- a/gcc/testsuite/g++.dg/modules/mod-decl-3.C
> +++ b/gcc/testsuite/g++.dg/modules/mod-decl-3.C
> @@ -22,5 +22,3 @@ namespace Bink
>     import  // { dg-error "does not name" }
>     ben;
>   }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/permissive-error-1.C b/gcc/testsuite/g++.dg/modules/permissive-error-1.C
> new file mode 100644
> index 00000000000..70ae1ec2dfc
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/permissive-error-1.C
> @@ -0,0 +1,10 @@
> +// { dg-additional-options "-fmodules-ts -fpermissive" }
> +// { dg-module-cmi !M }
> +
> +export module M;  // { dg-error "not writing module" }
> +
> +template <typename T> void f() {
> +  const int n = 42;
> +  ++n;  // { dg-warning "read-only" }
> +	// { dg-message "appeared here" "" { target *-*-* } .-1 }
> +}
> diff --git a/gcc/testsuite/g++.dg/modules/permissive-error-2.C b/gcc/testsuite/g++.dg/modules/permissive-error-2.C
> new file mode 100644
> index 00000000000..1e62d45207f
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/permissive-error-2.C
> @@ -0,0 +1,11 @@
> +// { dg-additional-options "-fmodules-ts -Wno-template-body" }
> +// { dg-module-cmi !M }
> +
> +export module M;  // { dg-error "not writing module" }
> +
> +template <typename T> void f() {
> +  const int n = 42;
> +  ++n;  // { dg-message "appeared here" }
> +}
> +
> +// { dg-message "enable \[^\n\r\]* for more details" "" { target *-*-* } 0 }
> diff --git a/gcc/testsuite/g++.dg/modules/pr99174.H b/gcc/testsuite/g++.dg/modules/pr99174.H
> index 62d5513b19a..60d01c59c77 100644
> --- a/gcc/testsuite/g++.dg/modules/pr99174.H
> +++ b/gcc/testsuite/g++.dg/modules/pr99174.H
> @@ -1,5 +1,3 @@
>   // { dg-additional-options -fmodule-header }
>   // { dg-module-cmi !{} }
>   import "pr99174.H"; // { dg-error "cannot import" }
> -
> -// { dg-prune-output {not writing module} }
> diff --git a/gcc/testsuite/g++.dg/modules/pr99468.H b/gcc/testsuite/g++.dg/modules/pr99468.H
> index b6be0c349d5..d7da3a83e1c 100644
> --- a/gcc/testsuite/g++.dg/modules/pr99468.H
> +++ b/gcc/testsuite/g++.dg/modules/pr99468.H
> @@ -4,4 +4,3 @@
>   module M; // { dg-error "module-declaration not permitted" }
>   
>   int i;
> -// { dg-prune-output "not writing" }
> diff --git a/gcc/testsuite/g++.dg/modules/token-1.C b/gcc/testsuite/g++.dg/modules/token-1.C
> index 50eee4c7ea1..db9a09b415f 100644
> --- a/gcc/testsuite/g++.dg/modules/token-1.C
> +++ b/gcc/testsuite/g++.dg/modules/token-1.C
> @@ -4,4 +4,3 @@ module ; // { dg-error "cannot be in included file" }
>   export module bob; // { dg-error "cannot be in included file" }
>   # 6 "" 2
>   // { dg-module-cmi !bob }
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/token-3.C b/gcc/testsuite/g++.dg/modules/token-3.C
> index 5bab426e2a6..1b4f66e6345 100644
> --- a/gcc/testsuite/g++.dg/modules/token-3.C
> +++ b/gcc/testsuite/g++.dg/modules/token-3.C
> @@ -3,4 +3,3 @@
>   export module bob; // { dg-error "in included file" }
>   # 6 "" 2
>   // { dg-module-cmi !bob }
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/token-4.C b/gcc/testsuite/g++.dg/modules/token-4.C
> index 5a852370d66..388da102f5f 100644
> --- a/gcc/testsuite/g++.dg/modules/token-4.C
> +++ b/gcc/testsuite/g++.dg/modules/token-4.C
> @@ -2,4 +2,3 @@
>   #define MODULE module   // { dg-error "does not name a type" }
>   export MODULE bob; // { dg-error "may only occur after" }
>   // { dg-module-cmi !bob }
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/token-5.C b/gcc/testsuite/g++.dg/modules/token-5.C
> index 29d3ec8fd70..8190f5ef6fb 100644
> --- a/gcc/testsuite/g++.dg/modules/token-5.C
> +++ b/gcc/testsuite/g++.dg/modules/token-5.C
> @@ -7,4 +7,3 @@ class Y;
>   
>   export module frob;
>   // { dg-module-cmi !frob }
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/using-10.C b/gcc/testsuite/g++.dg/modules/using-10.C
> index 5735353ee21..d468a36f5d8 100644
> --- a/gcc/testsuite/g++.dg/modules/using-10.C
> +++ b/gcc/testsuite/g++.dg/modules/using-10.C
> @@ -67,5 +67,3 @@ namespace t {
>   export using t::a;  // { dg-error "does not have external linkage" }
>   export using t::b;  // { dg-error "does not have external linkage" }
>   export using t::c;  // { dg-error "does not have external linkage" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/using-12.C b/gcc/testsuite/g++.dg/modules/using-12.C
> index 54eacf7276e..52ef3c6285d 100644
> --- a/gcc/testsuite/g++.dg/modules/using-12.C
> +++ b/gcc/testsuite/g++.dg/modules/using-12.C
> @@ -69,5 +69,3 @@ namespace t {
>     export using t::b;  // { dg-error "does not have external linkage" }
>     export using t::c;  // { dg-error "does not have external linkage" }
>   }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/using-3.C b/gcc/testsuite/g++.dg/modules/using-3.C
> index d21512fb20a..898618d6cc0 100644
> --- a/gcc/testsuite/g++.dg/modules/using-3.C
> +++ b/gcc/testsuite/g++.dg/modules/using-3.C
> @@ -13,5 +13,3 @@ using N::bar;
>   
>   export using N::foo; // { dg-error "does not have external linkage" }
>   export using N::bar; // { dg-error "does not have external linkage" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/using-9.C b/gcc/testsuite/g++.dg/modules/using-9.C
> index 4290280d897..8fb7b5e2c85 100644
> --- a/gcc/testsuite/g++.dg/modules/using-9.C
> +++ b/gcc/testsuite/g++.dg/modules/using-9.C
> @@ -9,5 +9,3 @@ namespace outer {
>   }
>   
>   export using outer::any_of;  // { dg-error "does not have external linkage" }
> -
> -// { dg-prune-output "not writing module" }
> diff --git a/gcc/testsuite/g++.dg/modules/using-enum-2.C b/gcc/testsuite/g++.dg/modules/using-enum-2.C
> index 813e2f630ab..12e37758e81 100644
> --- a/gcc/testsuite/g++.dg/modules/using-enum-2.C
> +++ b/gcc/testsuite/g++.dg/modules/using-enum-2.C
> @@ -19,5 +19,3 @@ export using enum s::e1;  // { dg-error "does not have external linkage" }
>   export using enum s::e2;  // { dg-error "does not have external linkage" }
>   export using enum m::e3;  // { dg-error "does not have external linkage" }
>   export using enum m::e4;  // { dg-error "does not have external linkage" }
> -
> -// { dg-prune-output "not writing module" }
diff mbox series

Patch

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 7c42aea05ee..07477d33955 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -3681,7 +3681,7 @@  class GTY((chain_next ("%h.parent"), for_user)) module_state {
 
  public:
   /* Read and write module.  */
-  void write_begin (elf_out *to, cpp_reader *,
+  bool write_begin (elf_out *to, cpp_reader *,
 		    module_state_config &, unsigned &crc);
   void write_end (elf_out *to, cpp_reader *,
 		  module_state_config &, unsigned &crc);
@@ -18317,7 +18317,7 @@  ool_cmp (const void *a_, const void *b_)
      MOD_SNAME_PFX.cfg      : config data
 */
 
-void
+bool
 module_state::write_begin (elf_out *to, cpp_reader *reader,
 			   module_state_config &config, unsigned &crc)
 {
@@ -18395,10 +18395,7 @@  module_state::write_begin (elf_out *to, cpp_reader *reader,
   table.find_dependencies (this);
 
   if (!table.finalize_dependencies ())
-    {
-      to->set_error ();
-      return;
-    }
+    return false;
 
 #if CHECKING_P
   /* We're done verifying at-most once reading, reset to verify
@@ -18595,6 +18592,8 @@  module_state::write_begin (elf_out *to, cpp_reader *reader,
   // so-controlled.
   if (false)
     write_env (to);
+
+  return true;
 }
 
 // Finish module writing after we've emitted all dynamic initializers. 
@@ -20847,20 +20846,29 @@  finish_module_processing (cpp_reader *reader)
 
       cookie = new module_processing_cookie (cmi_name, tmp_name, fd, e);
 
-      if (errorcount
-	  /* Don't write the module if it contains an erroneous template.  */
-	  || (erroneous_templates
-	      && !erroneous_templates->is_empty ()))
-	warning_at (state->loc, 0, "not writing module %qs due to errors",
-		    state->get_flatname ());
+      if (errorcount)
+	/* Don't write the module if we have reported errors.  */;
+      else if (erroneous_templates
+	       && !erroneous_templates->is_empty ())
+	{
+	  /* Don't write the module if it contains an erroneous template.
+	     Also emit notes about where errors occurred in case
+	     -Wno-template-body was passed.  */
+	  auto_diagnostic_group d;
+	  error_at (state->loc, "not writing module %qs due to errors "
+		    "in template bodies", state->get_flatname ());
+	  if (!warn_template_body)
+	    inform (state->loc, "enable %<-Wtemplate-body%> for more details");
+	  for (auto e : *erroneous_templates)
+	    inform (e.second, "first error in %qD appeared here", e.first);
+	}
       else if (cookie->out.begin ())
 	{
-	  cookie->began = true;
-	  auto loc = input_location;
 	  /* So crashes finger-point the module decl.  */
-	  input_location = state->loc;
-	  state->write_begin (&cookie->out, reader, cookie->config, cookie->crc);
-	  input_location = loc;
+	  iloc_sentinel ils = state->loc;
+	  if (state->write_begin (&cookie->out, reader, cookie->config,
+				  cookie->crc))
+	    cookie->began = true;
 	}
 
       dump.pop (n);
diff --git a/gcc/testsuite/g++.dg/modules/ambig-2_b.C b/gcc/testsuite/g++.dg/modules/ambig-2_b.C
index b94416aabbf..859cf14ac07 100644
--- a/gcc/testsuite/g++.dg/modules/ambig-2_b.C
+++ b/gcc/testsuite/g++.dg/modules/ambig-2_b.C
@@ -6,5 +6,3 @@  import A;
 
 extern "C++" int foo ();
 extern "C++" int bar ();  // { dg-error "ambiguating new declaration" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/atom-decl-2.C b/gcc/testsuite/g++.dg/modules/atom-decl-2.C
index b463dc8e214..43120152b45 100644
--- a/gcc/testsuite/g++.dg/modules/atom-decl-2.C
+++ b/gcc/testsuite/g++.dg/modules/atom-decl-2.C
@@ -2,5 +2,3 @@ 
 export module thing;
 int i;
 import baz; // { dg-error "must be contiguous" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/atom-pragma-3.C b/gcc/testsuite/g++.dg/modules/atom-pragma-3.C
index b95b2c8ad75..f2cadf02f2f 100644
--- a/gcc/testsuite/g++.dg/modules/atom-pragma-3.C
+++ b/gcc/testsuite/g++.dg/modules/atom-pragma-3.C
@@ -8,5 +8,3 @@  export module foo;
 import baz; // { dg-error "must be contiguous" }
 
 int i;
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C b/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C
index 28e54b808b2..42b84af651c 100644
--- a/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C
+++ b/gcc/testsuite/g++.dg/modules/atom-preamble-2_f.C
@@ -7,4 +7,3 @@  import kevin; // { dg-error "not be from header" }
 # 8 "" 2
 
 import kevin; // ok
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/block-decl-2.C b/gcc/testsuite/g++.dg/modules/block-decl-2.C
index 974e26f9b7a..d491a18dfb1 100644
--- a/gcc/testsuite/g++.dg/modules/block-decl-2.C
+++ b/gcc/testsuite/g++.dg/modules/block-decl-2.C
@@ -17,5 +17,3 @@  export extern "C++" auto foo() {
   };
   return X{};
 }
-
-// { dg-prune-output "failed to write compiled module" }
diff --git a/gcc/testsuite/g++.dg/modules/dir-only-4.C b/gcc/testsuite/g++.dg/modules/dir-only-4.C
index 80d6461e81f..9cb0587c0aa 100644
--- a/gcc/testsuite/g++.dg/modules/dir-only-4.C
+++ b/gcc/testsuite/g++.dg/modules/dir-only-4.C
@@ -7,4 +7,3 @@  export module foo;
 class import {};
 
 import x; // { dg-error "post-module-declaration" }
- // { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/enum-12.C b/gcc/testsuite/g++.dg/modules/enum-12.C
index cf8f445e076..3f29c52d59d 100644
--- a/gcc/testsuite/g++.dg/modules/enum-12.C
+++ b/gcc/testsuite/g++.dg/modules/enum-12.C
@@ -6,5 +6,3 @@  export module foo;
 namespace std {
   enum class align_val_t : decltype(sizeof(int)) {};  // { dg-error "in module .foo. conflicts with builtin" }
 }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C b/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C
index 3295a6af050..736e891d1c7 100644
--- a/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C
+++ b/gcc/testsuite/g++.dg/modules/exp-xlate-1_b.C
@@ -4,4 +4,3 @@  export module evil;
 
 export // { dg-error "not part of following" }
 #include "exp-xlate-1_a.H" // { dg-error "must be contiguous" }
-// { dg-prune-output {not writing module} }
diff --git a/gcc/testsuite/g++.dg/modules/export-1.C b/gcc/testsuite/g++.dg/modules/export-1.C
index 598814370ec..071f5ca2f35 100644
--- a/gcc/testsuite/g++.dg/modules/export-1.C
+++ b/gcc/testsuite/g++.dg/modules/export-1.C
@@ -24,5 +24,3 @@  export class A; // { dg-error "conflicting exporting for declaration" }
 
 template <typename T> struct B;
 export template <typename T> struct B {};  // { dg-error "conflicting exporting for declaration" }
-
-// { dg-warning "due to errors" "" { target *-*-* } 0 }
diff --git a/gcc/testsuite/g++.dg/modules/export-3.C b/gcc/testsuite/g++.dg/modules/export-3.C
index 76765fd2b2f..6af314b9519 100644
--- a/gcc/testsuite/g++.dg/modules/export-3.C
+++ b/gcc/testsuite/g++.dg/modules/export-3.C
@@ -26,5 +26,3 @@  namespace {
 }
 
 export namespace {}  // { dg-error "internal linkage" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/friend-3.C b/gcc/testsuite/g++.dg/modules/friend-3.C
index 48320eba46a..cf0bbb7de5e 100644
--- a/gcc/testsuite/g++.dg/modules/friend-3.C
+++ b/gcc/testsuite/g++.dg/modules/friend-3.C
@@ -31,4 +31,3 @@  export void quux (); // { dg-error "conflicting export" }
 void toto (); // not exported
 
 }
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/friend-5_b.C b/gcc/testsuite/g++.dg/modules/friend-5_b.C
index 6b561265155..b362cf82547 100644
--- a/gcc/testsuite/g++.dg/modules/friend-5_b.C
+++ b/gcc/testsuite/g++.dg/modules/friend-5_b.C
@@ -8,4 +8,3 @@  class B { // { dg-error "conflicts with import" }
   B() { object.value = 42; }
   A object;
 };
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C b/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C
index f33c464bee9..338c017c9b9 100644
--- a/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C
+++ b/gcc/testsuite/g++.dg/modules/inc-xlate-1_e.C
@@ -1,5 +1,3 @@ 
 // { dg-additional-options "-fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ -t\\ [srcdir]/inc-xlate-1.map" }
 export module bad;
 #include "inc-xlate-1_a.H"  // { dg-error "not be include-translated" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/internal-1.C b/gcc/testsuite/g++.dg/modules/internal-1.C
index 45d3bf06f28..9f7299a5fc7 100644
--- a/gcc/testsuite/g++.dg/modules/internal-1.C
+++ b/gcc/testsuite/g++.dg/modules/internal-1.C
@@ -1,6 +1,6 @@ 
 // { dg-additional-options "-fmodules-ts" }
 
-export module frob; // { dg-error "failed to write" }
+export module frob;
 // { dg-module-cmi !frob }
 
 namespace {
diff --git a/gcc/testsuite/g++.dg/modules/linkage-2.C b/gcc/testsuite/g++.dg/modules/linkage-2.C
index d913d6a30fc..4b20411572c 100644
--- a/gcc/testsuite/g++.dg/modules/linkage-2.C
+++ b/gcc/testsuite/g++.dg/modules/linkage-2.C
@@ -28,5 +28,3 @@  export void use() {
 // here is an exposure of this type, so this should be an error; we don't yet
 // implement this checking however.
 struct {} s;  // { dg-error "TU-local" "" { xfail *-*-* } }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/local-extern-1.C b/gcc/testsuite/g++.dg/modules/local-extern-1.C
index 7b016053d36..3e10c67d132 100644
--- a/gcc/testsuite/g++.dg/modules/local-extern-1.C
+++ b/gcc/testsuite/g++.dg/modules/local-extern-1.C
@@ -15,6 +15,3 @@  inline void dob ()
 {
   extern int bob; // { dg-error "block-scope extern" }
 }
-
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/main-1.C b/gcc/testsuite/g++.dg/modules/main-1.C
index 0d79edddb75..42929778481 100644
--- a/gcc/testsuite/g++.dg/modules/main-1.C
+++ b/gcc/testsuite/g++.dg/modules/main-1.C
@@ -1,5 +1,4 @@ 
 // { dg-additional-options "-fmodules-ts" }
-// { dg-prune-output "not writing module" }
 
 export module M;
 int main() {}  // { dg-error "attach" }
diff --git a/gcc/testsuite/g++.dg/modules/map-2.C b/gcc/testsuite/g++.dg/modules/map-2.C
index dceb1834196..94d3f7a1a41 100644
--- a/gcc/testsuite/g++.dg/modules/map-2.C
+++ b/gcc/testsuite/g++.dg/modules/map-2.C
@@ -7,5 +7,3 @@ 
 export module foo;
 // { dg-error "Interface: no such module" "" { target *-*-* } .-1 }
 // { dg-error "failed reading mapper" "" { target *-*-* } 0 }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/mod-decl-1.C b/gcc/testsuite/g++.dg/modules/mod-decl-1.C
index df398b3ef50..ac7bb84699a 100644
--- a/gcc/testsuite/g++.dg/modules/mod-decl-1.C
+++ b/gcc/testsuite/g++.dg/modules/mod-decl-1.C
@@ -27,5 +27,3 @@  void Bink ()
 
 module a.; // { dg-error "only permitted as" }
 
-// { dg-prune-output "not writing module" }
-
diff --git a/gcc/testsuite/g++.dg/modules/mod-decl-3.C b/gcc/testsuite/g++.dg/modules/mod-decl-3.C
index 16fa5a85a56..23ba7f13957 100644
--- a/gcc/testsuite/g++.dg/modules/mod-decl-3.C
+++ b/gcc/testsuite/g++.dg/modules/mod-decl-3.C
@@ -22,5 +22,3 @@  namespace Bink
   import  // { dg-error "does not name" }
   ben;
 }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/permissive-error-1.C b/gcc/testsuite/g++.dg/modules/permissive-error-1.C
new file mode 100644
index 00000000000..70ae1ec2dfc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/permissive-error-1.C
@@ -0,0 +1,10 @@ 
+// { dg-additional-options "-fmodules-ts -fpermissive" }
+// { dg-module-cmi !M }
+
+export module M;  // { dg-error "not writing module" }
+
+template <typename T> void f() {
+  const int n = 42;
+  ++n;  // { dg-warning "read-only" }
+	// { dg-message "appeared here" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/g++.dg/modules/permissive-error-2.C b/gcc/testsuite/g++.dg/modules/permissive-error-2.C
new file mode 100644
index 00000000000..1e62d45207f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/permissive-error-2.C
@@ -0,0 +1,11 @@ 
+// { dg-additional-options "-fmodules-ts -Wno-template-body" }
+// { dg-module-cmi !M }
+
+export module M;  // { dg-error "not writing module" }
+
+template <typename T> void f() {
+  const int n = 42;
+  ++n;  // { dg-message "appeared here" }
+}
+
+// { dg-message "enable \[^\n\r\]* for more details" "" { target *-*-* } 0 }
diff --git a/gcc/testsuite/g++.dg/modules/pr99174.H b/gcc/testsuite/g++.dg/modules/pr99174.H
index 62d5513b19a..60d01c59c77 100644
--- a/gcc/testsuite/g++.dg/modules/pr99174.H
+++ b/gcc/testsuite/g++.dg/modules/pr99174.H
@@ -1,5 +1,3 @@ 
 // { dg-additional-options -fmodule-header }
 // { dg-module-cmi !{} }
 import "pr99174.H"; // { dg-error "cannot import" }
-
-// { dg-prune-output {not writing module} }
diff --git a/gcc/testsuite/g++.dg/modules/pr99468.H b/gcc/testsuite/g++.dg/modules/pr99468.H
index b6be0c349d5..d7da3a83e1c 100644
--- a/gcc/testsuite/g++.dg/modules/pr99468.H
+++ b/gcc/testsuite/g++.dg/modules/pr99468.H
@@ -4,4 +4,3 @@ 
 module M; // { dg-error "module-declaration not permitted" }
 
 int i;
-// { dg-prune-output "not writing" }
diff --git a/gcc/testsuite/g++.dg/modules/token-1.C b/gcc/testsuite/g++.dg/modules/token-1.C
index 50eee4c7ea1..db9a09b415f 100644
--- a/gcc/testsuite/g++.dg/modules/token-1.C
+++ b/gcc/testsuite/g++.dg/modules/token-1.C
@@ -4,4 +4,3 @@  module ; // { dg-error "cannot be in included file" }
 export module bob; // { dg-error "cannot be in included file" }
 # 6 "" 2
 // { dg-module-cmi !bob }
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/token-3.C b/gcc/testsuite/g++.dg/modules/token-3.C
index 5bab426e2a6..1b4f66e6345 100644
--- a/gcc/testsuite/g++.dg/modules/token-3.C
+++ b/gcc/testsuite/g++.dg/modules/token-3.C
@@ -3,4 +3,3 @@ 
 export module bob; // { dg-error "in included file" }
 # 6 "" 2
 // { dg-module-cmi !bob }
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/token-4.C b/gcc/testsuite/g++.dg/modules/token-4.C
index 5a852370d66..388da102f5f 100644
--- a/gcc/testsuite/g++.dg/modules/token-4.C
+++ b/gcc/testsuite/g++.dg/modules/token-4.C
@@ -2,4 +2,3 @@ 
 #define MODULE module   // { dg-error "does not name a type" }
 export MODULE bob; // { dg-error "may only occur after" }
 // { dg-module-cmi !bob }
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/token-5.C b/gcc/testsuite/g++.dg/modules/token-5.C
index 29d3ec8fd70..8190f5ef6fb 100644
--- a/gcc/testsuite/g++.dg/modules/token-5.C
+++ b/gcc/testsuite/g++.dg/modules/token-5.C
@@ -7,4 +7,3 @@  class Y;
 
 export module frob;
 // { dg-module-cmi !frob }
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-10.C b/gcc/testsuite/g++.dg/modules/using-10.C
index 5735353ee21..d468a36f5d8 100644
--- a/gcc/testsuite/g++.dg/modules/using-10.C
+++ b/gcc/testsuite/g++.dg/modules/using-10.C
@@ -67,5 +67,3 @@  namespace t {
 export using t::a;  // { dg-error "does not have external linkage" }
 export using t::b;  // { dg-error "does not have external linkage" }
 export using t::c;  // { dg-error "does not have external linkage" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-12.C b/gcc/testsuite/g++.dg/modules/using-12.C
index 54eacf7276e..52ef3c6285d 100644
--- a/gcc/testsuite/g++.dg/modules/using-12.C
+++ b/gcc/testsuite/g++.dg/modules/using-12.C
@@ -69,5 +69,3 @@  namespace t {
   export using t::b;  // { dg-error "does not have external linkage" }
   export using t::c;  // { dg-error "does not have external linkage" }
 }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-3.C b/gcc/testsuite/g++.dg/modules/using-3.C
index d21512fb20a..898618d6cc0 100644
--- a/gcc/testsuite/g++.dg/modules/using-3.C
+++ b/gcc/testsuite/g++.dg/modules/using-3.C
@@ -13,5 +13,3 @@  using N::bar;
 
 export using N::foo; // { dg-error "does not have external linkage" }
 export using N::bar; // { dg-error "does not have external linkage" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-9.C b/gcc/testsuite/g++.dg/modules/using-9.C
index 4290280d897..8fb7b5e2c85 100644
--- a/gcc/testsuite/g++.dg/modules/using-9.C
+++ b/gcc/testsuite/g++.dg/modules/using-9.C
@@ -9,5 +9,3 @@  namespace outer {
 }
 
 export using outer::any_of;  // { dg-error "does not have external linkage" }
-
-// { dg-prune-output "not writing module" }
diff --git a/gcc/testsuite/g++.dg/modules/using-enum-2.C b/gcc/testsuite/g++.dg/modules/using-enum-2.C
index 813e2f630ab..12e37758e81 100644
--- a/gcc/testsuite/g++.dg/modules/using-enum-2.C
+++ b/gcc/testsuite/g++.dg/modules/using-enum-2.C
@@ -19,5 +19,3 @@  export using enum s::e1;  // { dg-error "does not have external linkage" }
 export using enum s::e2;  // { dg-error "does not have external linkage" }
 export using enum m::e3;  // { dg-error "does not have external linkage" }
 export using enum m::e4;  // { dg-error "does not have external linkage" }
-
-// { dg-prune-output "not writing module" }