diff mbox series

[v2,RFA] diagnostic: add permerror variants with opt

Message ID 20231003210916.1027930-1-jason@redhat.com
State New
Headers show
Series [v2,RFA] diagnostic: add permerror variants with opt | expand

Commit Message

Jason Merrill Oct. 3, 2023, 9:09 p.m. UTC
This revision changes from using DK_PEDWARN for permerror-with-option to using
DK_PERMERROR.

Tested x86_64-pc-linux-gnu.  OK for trunk?

-- 8< --

In the discussion of promoting some pedwarns to be errors by default, rather
than move them all into -fpermissive it seems to me to make sense to support
DK_PERMERROR with an option flag.  This way will also work with
-fpermissive, but users can also still use -Wno-error=narrowing to downgrade
that specific diagnostic rather than everything affected by -fpermissive.

So, for diagnostics that we want to make errors by default we can just
change the pedwarn call to permerror.

The tests check desired behavior for such a permerror in a system header
with various flags.  The patch preserves the existing permerror behavior of
ignoring -w and system headers by default, but respecting them when
downgraded to a warning by -fpermissive.

This seems similar to but a bit better than the approach of forcing
-pedantic-errors that I previously used for -Wnarrowing: specifically, in
that now -w by itself is not enough to silence the -Wnarrowing
error (integer-pack2.C).

gcc/ChangeLog:

	* doc/invoke.texi: Move -fpermissive to Warning Options.
	* diagnostic.cc (update_effective_level_from_pragmas): Remove
	redundant system header check.
	(diagnostic_report_diagnostic): Move down syshdr/-w check.
	(diagnostic_impl): Handle DK_PERMERROR with an option number.
	(permerror): Add new overloads.
	* diagnostic-core.h (permerror): Declare them.

gcc/cp/ChangeLog:

	* typeck2.cc (check_narrowing): Use permerror.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/integer-pack2.C: Add -fpermissive.
	* g++.dg/diagnostic/sys-narrow.h: New test.
	* g++.dg/diagnostic/sys-narrow1.C: New test.
	* g++.dg/diagnostic/sys-narrow1a.C: New test.
	* g++.dg/diagnostic/sys-narrow1b.C: New test.
	* g++.dg/diagnostic/sys-narrow1c.C: New test.
	* g++.dg/diagnostic/sys-narrow1d.C: New test.
	* g++.dg/diagnostic/sys-narrow1e.C: New test.
	* g++.dg/diagnostic/sys-narrow1f.C: New test.
	* g++.dg/diagnostic/sys-narrow1g.C: New test.
	* g++.dg/diagnostic/sys-narrow1h.C: New test.
	* g++.dg/diagnostic/sys-narrow1i.C: New test.
---
 gcc/doc/invoke.texi                           | 22 +++---
 gcc/diagnostic-core.h                         |  3 +
 gcc/testsuite/g++.dg/diagnostic/sys-narrow.h  |  2 +
 gcc/cp/typeck2.cc                             | 10 +--
 gcc/diagnostic.cc                             | 67 ++++++++++++-------
 gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C |  4 ++
 .../g++.dg/diagnostic/sys-narrow1a.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1b.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1c.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1d.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1e.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1f.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1g.C          |  5 ++
 .../g++.dg/diagnostic/sys-narrow1h.C          |  6 ++
 .../g++.dg/diagnostic/sys-narrow1i.C          |  6 ++
 gcc/testsuite/g++.dg/ext/integer-pack2.C      |  2 +-
 16 files changed, 117 insertions(+), 40 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C


base-commit: 41d1c9a97953b457146c1dbeea2a4f19bfbb0b6e

Comments

Florian Weimer Oct. 4, 2023, 7:07 a.m. UTC | #1
* Jason Merrill:

> @@ -6159,6 +6153,18 @@ errors by @option{-pedantic-errors}.  For instance:
>  -Wwrite-strings @r{(C++11 or later)}
>  }
>  
> +@opindex fpermissive
> +@item -fpermissive
> +Downgrade some required diagnostics about nonconformant code from
> +errors to warnings.  Thus, using @option{-fpermissive} allows some
> +nonconforming code to compile.  Some C++ diagnostics are controlled
> +only by this flag, but it also downgrades some diagnostics that have
> +their own flag:
> +
> +@gccoptlist{
> +-Wnarrowing @r{(C++)}
> +}
> +
>  @opindex Wall
>  @opindex Wno-all
>  @item -Wall

Does compiling with -Wno-narrowing also accept the obsolete constructs?
The documentation isn't clear about it.  The existing test
gcc/testsuite/g++.dg/cpp0x/initlist55.C suggests it's possible.  Maybe
add an explicit example to the documentation?

What about the impact of -w?

As far as the internal API is concerned, will there be a way to query
whether -Wno-narrowing etc. have been specified?  We could use this in
the C frontend where we might want to run different code in some cases.
Without implicit ints, for example, we know that identifiers at certain
positions must be types, so we can type spelling hints to errors.

Thanks,
Florian
Jason Merrill Oct. 4, 2023, 7:16 p.m. UTC | #2
On 10/4/23 03:07, Florian Weimer wrote:
> * Jason Merrill:
> 
>> @@ -6159,6 +6153,18 @@ errors by @option{-pedantic-errors}.  For instance:
>>   -Wwrite-strings @r{(C++11 or later)}
>>   }
>>   
>> +@opindex fpermissive
>> +@item -fpermissive
>> +Downgrade some required diagnostics about nonconformant code from
>> +errors to warnings.  Thus, using @option{-fpermissive} allows some
>> +nonconforming code to compile.  Some C++ diagnostics are controlled
>> +only by this flag, but it also downgrades some diagnostics that have
>> +their own flag:
>> +
>> +@gccoptlist{
>> +-Wnarrowing @r{(C++)}
>> +}
>> +
>>   @opindex Wall
>>   @opindex Wno-all
>>   @item -Wall
> 
> Does compiling with -Wno-narrowing also accept the obsolete constructs?
> The documentation isn't clear about it.  The existing test
> gcc/testsuite/g++.dg/cpp0x/initlist55.C suggests it's possible.  Maybe
> add an explicit example to the documentation?

The documentation for -Wnarrowing already says that -Wno-narrowing 
suppresses the diagnostic.  It seems clear to me that if there's no 
error, the construct is accepted?

> What about the impact of -w?

As I said in the patch comment, -w by itself has no effect. 
-fpermissive -w silences the diagnostic.

> As far as the internal API is concerned, will there be a way to query
> whether -Wno-narrowing etc. have been specified?

There's warning_enabled_at, but that doesn't account for the different 
rules for permerrors, such as the above -w behavior.  We could add a 
similar function for permerrors, that could also indicate whether the 
diagnostic is a warning or error?

More generally there's OPTION_SET_P.

Jason
Jason Merrill Oct. 17, 2023, 7:50 p.m. UTC | #3
Ping?

On 10/3/23 17:09, Jason Merrill wrote:
> This revision changes from using DK_PEDWARN for permerror-with-option to using
> DK_PERMERROR.
> 
> Tested x86_64-pc-linux-gnu.  OK for trunk?
> 
> -- 8< --
> 
> In the discussion of promoting some pedwarns to be errors by default, rather
> than move them all into -fpermissive it seems to me to make sense to support
> DK_PERMERROR with an option flag.  This way will also work with
> -fpermissive, but users can also still use -Wno-error=narrowing to downgrade
> that specific diagnostic rather than everything affected by -fpermissive.
> 
> So, for diagnostics that we want to make errors by default we can just
> change the pedwarn call to permerror.
> 
> The tests check desired behavior for such a permerror in a system header
> with various flags.  The patch preserves the existing permerror behavior of
> ignoring -w and system headers by default, but respecting them when
> downgraded to a warning by -fpermissive.
> 
> This seems similar to but a bit better than the approach of forcing
> -pedantic-errors that I previously used for -Wnarrowing: specifically, in
> that now -w by itself is not enough to silence the -Wnarrowing
> error (integer-pack2.C).
> 
> gcc/ChangeLog:
> 
> 	* doc/invoke.texi: Move -fpermissive to Warning Options.
> 	* diagnostic.cc (update_effective_level_from_pragmas): Remove
> 	redundant system header check.
> 	(diagnostic_report_diagnostic): Move down syshdr/-w check.
> 	(diagnostic_impl): Handle DK_PERMERROR with an option number.
> 	(permerror): Add new overloads.
> 	* diagnostic-core.h (permerror): Declare them.
> 
> gcc/cp/ChangeLog:
> 
> 	* typeck2.cc (check_narrowing): Use permerror.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/integer-pack2.C: Add -fpermissive.
> 	* g++.dg/diagnostic/sys-narrow.h: New test.
> 	* g++.dg/diagnostic/sys-narrow1.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1a.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1b.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1c.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1d.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1e.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1f.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1g.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1h.C: New test.
> 	* g++.dg/diagnostic/sys-narrow1i.C: New test.
> ---
>   gcc/doc/invoke.texi                           | 22 +++---
>   gcc/diagnostic-core.h                         |  3 +
>   gcc/testsuite/g++.dg/diagnostic/sys-narrow.h  |  2 +
>   gcc/cp/typeck2.cc                             | 10 +--
>   gcc/diagnostic.cc                             | 67 ++++++++++++-------
>   gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C |  4 ++
>   .../g++.dg/diagnostic/sys-narrow1a.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1b.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1c.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1d.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1e.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1f.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1g.C          |  5 ++
>   .../g++.dg/diagnostic/sys-narrow1h.C          |  6 ++
>   .../g++.dg/diagnostic/sys-narrow1i.C          |  6 ++
>   gcc/testsuite/g++.dg/ext/integer-pack2.C      |  2 +-
>   16 files changed, 117 insertions(+), 40 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
> 
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 4085fc90907..6b6506a75b2 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -231,7 +231,7 @@ in the following sections.
>   -fnew-inheriting-ctors
>   -fnew-ttp-matching
>   -fno-nonansi-builtins  -fnothrow-opt  -fno-operator-names
> --fno-optional-diags  -fpermissive
> +-fno-optional-diags
>   -fno-pretty-templates
>   -fno-rtti  -fsized-deallocation
>   -ftemplate-backtrace-limit=@var{n}
> @@ -323,7 +323,7 @@ Objective-C and Objective-C++ Dialects}.
>   @item Warning Options
>   @xref{Warning Options,,Options to Request or Suppress Warnings}.
>   @gccoptlist{-fsyntax-only  -fmax-errors=@var{n}  -Wpedantic
> --pedantic-errors
> +-pedantic-errors -fpermissive
>   -w  -Wextra  -Wall  -Wabi=@var{n}
>   -Waddress  -Wno-address-of-packed-member  -Waggregate-return
>   -Walloc-size-larger-than=@var{byte-size}  -Walloc-zero
> @@ -3494,12 +3494,6 @@ Disable diagnostics that the standard says a compiler does not need to
>   issue.  Currently, the only such diagnostic issued by G++ is the one for
>   a name having multiple meanings within a class.
>   
> -@opindex fpermissive
> -@item -fpermissive
> -Downgrade some diagnostics about nonconformant code from errors to
> -warnings.  Thus, using @option{-fpermissive} allows some
> -nonconforming code to compile.
> -
>   @opindex fno-pretty-templates
>   @opindex fpretty-templates
>   @item -fno-pretty-templates
> @@ -6159,6 +6153,18 @@ errors by @option{-pedantic-errors}.  For instance:
>   -Wwrite-strings @r{(C++11 or later)}
>   }
>   
> +@opindex fpermissive
> +@item -fpermissive
> +Downgrade some required diagnostics about nonconformant code from
> +errors to warnings.  Thus, using @option{-fpermissive} allows some
> +nonconforming code to compile.  Some C++ diagnostics are controlled
> +only by this flag, but it also downgrades some diagnostics that have
> +their own flag:
> +
> +@gccoptlist{
> +-Wnarrowing @r{(C++)}
> +}
> +
>   @opindex Wall
>   @opindex Wno-all
>   @item -Wall
> diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
> index c9e27fd2e6e..2d9909f18bd 100644
> --- a/gcc/diagnostic-core.h
> +++ b/gcc/diagnostic-core.h
> @@ -105,6 +105,9 @@ extern bool pedwarn (rich_location *, int, const char *, ...)
>   extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
>   extern bool permerror (rich_location *, const char *,
>   				   ...) ATTRIBUTE_GCC_DIAG(2,3);
> +extern bool permerror (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
> +extern bool permerror (rich_location *, int, const char *,
> +		       ...) ATTRIBUTE_GCC_DIAG(3,4);
>   extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
>   extern void sorry_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
>   extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h b/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
> new file mode 100644
> index 00000000000..ff042c54a10
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
> @@ -0,0 +1,2 @@
> +#pragma GCC system_header
> +int i = { 2.4 }; // C++11 error: narrowing conversion
> diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
> index cd1ea045720..ab819d4e49d 100644
> --- a/gcc/cp/typeck2.cc
> +++ b/gcc/cp/typeck2.cc
> @@ -1109,15 +1109,11 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain,
>         else if (complain & tf_error)
>   	{
>   	  int savederrorcount = errorcount;
> -	  if (!flag_permissive)
> -	    global_dc->pedantic_errors = 1;
> -	  auto s = make_temp_override (global_dc->dc_warn_system_headers, true);
> -	  pedwarn (loc, OPT_Wnarrowing,
> -		   "narrowing conversion of %qE from %qH to %qI",
> -		   init, ftype, type);
> +	  permerror (loc, OPT_Wnarrowing,
> +		     "narrowing conversion of %qE from %qH to %qI",
> +		     init, ftype, type);
>   	  if (errorcount == savederrorcount)
>   	    ok = true;
> -	  global_dc->pedantic_errors = flag_pedantic_errors;
>   	}
>       }
>   
> diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
> index 65a78840a66..fcbd69f2b8b 100644
> --- a/gcc/diagnostic.cc
> +++ b/gcc/diagnostic.cc
> @@ -1232,14 +1232,6 @@ static diagnostic_t
>   update_effective_level_from_pragmas (diagnostic_context *context,
>   				     diagnostic_info *diagnostic)
>   {
> -  if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
> -    {
> -      /* Ignore the diagnostic if all the inlined locations are
> -	 in system headers and -Wno-system-headers is in effect.  */
> -      diagnostic->kind = DK_IGNORED;
> -      return DK_IGNORED;
> -    }
> -
>     if (context->n_classification_history <= 0)
>       return DK_UNSPECIFIED;
>   
> @@ -1480,24 +1472,16 @@ bool
>   diagnostic_report_diagnostic (diagnostic_context *context,
>   			      diagnostic_info *diagnostic)
>   {
> -  location_t location = diagnostic_location (diagnostic);
>     diagnostic_t orig_diag_kind = diagnostic->kind;
>   
>     gcc_assert (context->m_output_format);
>   
>     /* Give preference to being able to inhibit warnings, before they
>        get reclassified to something else.  */
> -  bool report_warning_p = true;
> -  if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
> -    {
> -      if (context->dc_inhibit_warnings)
> -	return false;
> -      /* Remember the result of the overall system header warning setting
> -	 but proceed to also check the inlining context.  */
> -      report_warning_p = diagnostic_report_warnings_p (context, location);
> -      if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
> -	return false;
> -    }
> +  bool was_warning = (diagnostic->kind == DK_WARNING
> +		      || diagnostic->kind == DK_PEDWARN);
> +  if (was_warning && context->dc_inhibit_warnings)
> +    return false;
>   
>     if (diagnostic->kind == DK_PEDWARN)
>       {
> @@ -1537,9 +1521,12 @@ diagnostic_report_diagnostic (diagnostic_context *context,
>     if (!diagnostic_enabled (context, diagnostic))
>       return false;
>   
> -  if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
> -    /* Bail if the warning is not to be reported because all locations
> -       in the inlining stack (if there is one) are in system headers.  */
> +  if ((was_warning || diagnostic->kind == DK_WARNING)
> +      && ((!context->dc_warn_system_headers
> +	   && diagnostic->m_iinfo.m_allsyslocs)
> +	  || context->dc_inhibit_warnings))
> +    /* Bail if the warning is not to be reported because all locations in the
> +       inlining stack (if there is one) are in system headers.  */
>       return false;
>   
>     if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
> @@ -1733,7 +1720,8 @@ diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
>       {
>         diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
>   			   permissive_error_kind (global_dc));
> -      diagnostic.option_index = permissive_error_option (global_dc);
> +      diagnostic.option_index = (opt != -1 ? opt
> +				 : permissive_error_option (global_dc));
>       }
>     else
>       {
> @@ -2029,6 +2017,37 @@ permerror (rich_location *richloc, const char *gmsgid, ...)
>     return ret;
>   }
>   
> +/* Similar to the above, but controlled by a flag other than -fpermissive.
> +   As above, an error by default or a warning with -fpermissive, but this
> +   diagnostic can also be downgraded by -Wno-error=opt.  */
> +
> +bool
> +permerror (location_t location, int opt, const char *gmsgid, ...)
> +{
> +  auto_diagnostic_group d;
> +  va_list ap;
> +  va_start (ap, gmsgid);
> +  rich_location richloc (line_table, location);
> +  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PERMERROR);
> +  va_end (ap);
> +  return ret;
> +}
> +
> +/* Same as "permerror" above, but at RICHLOC.  */
> +
> +bool
> +permerror (rich_location *richloc, int opt, const char *gmsgid, ...)
> +{
> +  gcc_assert (richloc);
> +
> +  auto_diagnostic_group d;
> +  va_list ap;
> +  va_start (ap, gmsgid);
> +  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PERMERROR);
> +  va_end (ap);
> +  return ret;
> +}
> +
>   /* A hard error: the code is definitely ill-formed, and an object file
>      will not be produced.  */
>   void
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
> new file mode 100644
> index 00000000000..7d3bca9f231
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
> @@ -0,0 +1,4 @@
> +// { dg-do compile { target c++11 } }
> +
> +// { dg-error "narrowing" "" { target *-*-* } 2 }
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
> new file mode 100644
> index 00000000000..58cdaf273c9
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-w" }
> +
> +// { dg-error "narrowing" "" { target *-*-* } 2 }
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
> new file mode 100644
> index 00000000000..8528f5d357b
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-Wno-error" }
> +
> +// { dg-error "narrowing" "" { target *-*-* } 2 }
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
> new file mode 100644
> index 00000000000..1243eb00eef
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-additional-options "-Wno-error=narrowing" }
> +
> +// No diagnostic.
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
> new file mode 100644
> index 00000000000..0653df9c238
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-fpermissive" }
> +
> +// No diagnostic.
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
> new file mode 100644
> index 00000000000..d2198298e7c
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-fpermissive -Wsystem-headers" }
> +
> +// { dg-warning "narrowing" "" { target *-*-* } 2 }
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
> new file mode 100644
> index 00000000000..28f7fe2e84c
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-Wno-narrowing" }
> +
> +// No diagnostic
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
> new file mode 100644
> index 00000000000..d052beab031
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
> @@ -0,0 +1,5 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-Wno-error=narrowing -Wsystem-headers" }
> +
> +// { dg-warning "narrowing" "" { target *-*-* } 2 }
> +#include "sys-narrow.h"
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
> new file mode 100644
> index 00000000000..e96ee1fc134
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
> @@ -0,0 +1,6 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-Wno-error=narrowing -w" }
> +
> +// No diagnostic
> +int i = { 2.4 }; // C++11 error: narrowing conversion
> +
> diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
> new file mode 100644
> index 00000000000..f7d958548cf
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
> @@ -0,0 +1,6 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-fpermissive -w" }
> +
> +// No diagnostic
> +int i = { 2.4 }; // C++11 error: narrowing conversion
> +
> diff --git a/gcc/testsuite/g++.dg/ext/integer-pack2.C b/gcc/testsuite/g++.dg/ext/integer-pack2.C
> index 406e195574c..fa6a8813368 100644
> --- a/gcc/testsuite/g++.dg/ext/integer-pack2.C
> +++ b/gcc/testsuite/g++.dg/ext/integer-pack2.C
> @@ -1,5 +1,5 @@
>   // { dg-do compile { target { c++11 && int32 } } }
> -// { dg-options -w }
> +// { dg-options "-fpermissive -w" }
>   
>   template<typename T, T...> struct integer_sequence { };
>   template<typename T, T num>
> 
> base-commit: 41d1c9a97953b457146c1dbeea2a4f19bfbb0b6e
Richard Biener Oct. 18, 2023, 6:23 a.m. UTC | #4
On Tue, Oct 17, 2023 at 9:51 PM Jason Merrill <jason@redhat.com> wrote:
>
> Ping?

OK.

Thanks,
Richard.

> On 10/3/23 17:09, Jason Merrill wrote:
> > This revision changes from using DK_PEDWARN for permerror-with-option to using
> > DK_PERMERROR.
> >
> > Tested x86_64-pc-linux-gnu.  OK for trunk?
> >
> > -- 8< --
> >
> > In the discussion of promoting some pedwarns to be errors by default, rather
> > than move them all into -fpermissive it seems to me to make sense to support
> > DK_PERMERROR with an option flag.  This way will also work with
> > -fpermissive, but users can also still use -Wno-error=narrowing to downgrade
> > that specific diagnostic rather than everything affected by -fpermissive.
> >
> > So, for diagnostics that we want to make errors by default we can just
> > change the pedwarn call to permerror.
> >
> > The tests check desired behavior for such a permerror in a system header
> > with various flags.  The patch preserves the existing permerror behavior of
> > ignoring -w and system headers by default, but respecting them when
> > downgraded to a warning by -fpermissive.
> >
> > This seems similar to but a bit better than the approach of forcing
> > -pedantic-errors that I previously used for -Wnarrowing: specifically, in
> > that now -w by itself is not enough to silence the -Wnarrowing
> > error (integer-pack2.C).
> >
> > gcc/ChangeLog:
> >
> >       * doc/invoke.texi: Move -fpermissive to Warning Options.
> >       * diagnostic.cc (update_effective_level_from_pragmas): Remove
> >       redundant system header check.
> >       (diagnostic_report_diagnostic): Move down syshdr/-w check.
> >       (diagnostic_impl): Handle DK_PERMERROR with an option number.
> >       (permerror): Add new overloads.
> >       * diagnostic-core.h (permerror): Declare them.
> >
> > gcc/cp/ChangeLog:
> >
> >       * typeck2.cc (check_narrowing): Use permerror.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * g++.dg/ext/integer-pack2.C: Add -fpermissive.
> >       * g++.dg/diagnostic/sys-narrow.h: New test.
> >       * g++.dg/diagnostic/sys-narrow1.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1a.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1b.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1c.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1d.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1e.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1f.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1g.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1h.C: New test.
> >       * g++.dg/diagnostic/sys-narrow1i.C: New test.
> > ---
> >   gcc/doc/invoke.texi                           | 22 +++---
> >   gcc/diagnostic-core.h                         |  3 +
> >   gcc/testsuite/g++.dg/diagnostic/sys-narrow.h  |  2 +
> >   gcc/cp/typeck2.cc                             | 10 +--
> >   gcc/diagnostic.cc                             | 67 ++++++++++++-------
> >   gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C |  4 ++
> >   .../g++.dg/diagnostic/sys-narrow1a.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1b.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1c.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1d.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1e.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1f.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1g.C          |  5 ++
> >   .../g++.dg/diagnostic/sys-narrow1h.C          |  6 ++
> >   .../g++.dg/diagnostic/sys-narrow1i.C          |  6 ++
> >   gcc/testsuite/g++.dg/ext/integer-pack2.C      |  2 +-
> >   16 files changed, 117 insertions(+), 40 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
> >   create mode 100644 gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
> >
> > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> > index 4085fc90907..6b6506a75b2 100644
> > --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -231,7 +231,7 @@ in the following sections.
> >   -fnew-inheriting-ctors
> >   -fnew-ttp-matching
> >   -fno-nonansi-builtins  -fnothrow-opt  -fno-operator-names
> > --fno-optional-diags  -fpermissive
> > +-fno-optional-diags
> >   -fno-pretty-templates
> >   -fno-rtti  -fsized-deallocation
> >   -ftemplate-backtrace-limit=@var{n}
> > @@ -323,7 +323,7 @@ Objective-C and Objective-C++ Dialects}.
> >   @item Warning Options
> >   @xref{Warning Options,,Options to Request or Suppress Warnings}.
> >   @gccoptlist{-fsyntax-only  -fmax-errors=@var{n}  -Wpedantic
> > --pedantic-errors
> > +-pedantic-errors -fpermissive
> >   -w  -Wextra  -Wall  -Wabi=@var{n}
> >   -Waddress  -Wno-address-of-packed-member  -Waggregate-return
> >   -Walloc-size-larger-than=@var{byte-size}  -Walloc-zero
> > @@ -3494,12 +3494,6 @@ Disable diagnostics that the standard says a compiler does not need to
> >   issue.  Currently, the only such diagnostic issued by G++ is the one for
> >   a name having multiple meanings within a class.
> >
> > -@opindex fpermissive
> > -@item -fpermissive
> > -Downgrade some diagnostics about nonconformant code from errors to
> > -warnings.  Thus, using @option{-fpermissive} allows some
> > -nonconforming code to compile.
> > -
> >   @opindex fno-pretty-templates
> >   @opindex fpretty-templates
> >   @item -fno-pretty-templates
> > @@ -6159,6 +6153,18 @@ errors by @option{-pedantic-errors}.  For instance:
> >   -Wwrite-strings @r{(C++11 or later)}
> >   }
> >
> > +@opindex fpermissive
> > +@item -fpermissive
> > +Downgrade some required diagnostics about nonconformant code from
> > +errors to warnings.  Thus, using @option{-fpermissive} allows some
> > +nonconforming code to compile.  Some C++ diagnostics are controlled
> > +only by this flag, but it also downgrades some diagnostics that have
> > +their own flag:
> > +
> > +@gccoptlist{
> > +-Wnarrowing @r{(C++)}
> > +}
> > +
> >   @opindex Wall
> >   @opindex Wno-all
> >   @item -Wall
> > diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
> > index c9e27fd2e6e..2d9909f18bd 100644
> > --- a/gcc/diagnostic-core.h
> > +++ b/gcc/diagnostic-core.h
> > @@ -105,6 +105,9 @@ extern bool pedwarn (rich_location *, int, const char *, ...)
> >   extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
> >   extern bool permerror (rich_location *, const char *,
> >                                  ...) ATTRIBUTE_GCC_DIAG(2,3);
> > +extern bool permerror (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
> > +extern bool permerror (rich_location *, int, const char *,
> > +                    ...) ATTRIBUTE_GCC_DIAG(3,4);
> >   extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
> >   extern void sorry_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
> >   extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h b/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
> > new file mode 100644
> > index 00000000000..ff042c54a10
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
> > @@ -0,0 +1,2 @@
> > +#pragma GCC system_header
> > +int i = { 2.4 }; // C++11 error: narrowing conversion
> > diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
> > index cd1ea045720..ab819d4e49d 100644
> > --- a/gcc/cp/typeck2.cc
> > +++ b/gcc/cp/typeck2.cc
> > @@ -1109,15 +1109,11 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain,
> >         else if (complain & tf_error)
> >       {
> >         int savederrorcount = errorcount;
> > -       if (!flag_permissive)
> > -         global_dc->pedantic_errors = 1;
> > -       auto s = make_temp_override (global_dc->dc_warn_system_headers, true);
> > -       pedwarn (loc, OPT_Wnarrowing,
> > -                "narrowing conversion of %qE from %qH to %qI",
> > -                init, ftype, type);
> > +       permerror (loc, OPT_Wnarrowing,
> > +                  "narrowing conversion of %qE from %qH to %qI",
> > +                  init, ftype, type);
> >         if (errorcount == savederrorcount)
> >           ok = true;
> > -       global_dc->pedantic_errors = flag_pedantic_errors;
> >       }
> >       }
> >
> > diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
> > index 65a78840a66..fcbd69f2b8b 100644
> > --- a/gcc/diagnostic.cc
> > +++ b/gcc/diagnostic.cc
> > @@ -1232,14 +1232,6 @@ static diagnostic_t
> >   update_effective_level_from_pragmas (diagnostic_context *context,
> >                                    diagnostic_info *diagnostic)
> >   {
> > -  if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
> > -    {
> > -      /* Ignore the diagnostic if all the inlined locations are
> > -      in system headers and -Wno-system-headers is in effect.  */
> > -      diagnostic->kind = DK_IGNORED;
> > -      return DK_IGNORED;
> > -    }
> > -
> >     if (context->n_classification_history <= 0)
> >       return DK_UNSPECIFIED;
> >
> > @@ -1480,24 +1472,16 @@ bool
> >   diagnostic_report_diagnostic (diagnostic_context *context,
> >                             diagnostic_info *diagnostic)
> >   {
> > -  location_t location = diagnostic_location (diagnostic);
> >     diagnostic_t orig_diag_kind = diagnostic->kind;
> >
> >     gcc_assert (context->m_output_format);
> >
> >     /* Give preference to being able to inhibit warnings, before they
> >        get reclassified to something else.  */
> > -  bool report_warning_p = true;
> > -  if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
> > -    {
> > -      if (context->dc_inhibit_warnings)
> > -     return false;
> > -      /* Remember the result of the overall system header warning setting
> > -      but proceed to also check the inlining context.  */
> > -      report_warning_p = diagnostic_report_warnings_p (context, location);
> > -      if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
> > -     return false;
> > -    }
> > +  bool was_warning = (diagnostic->kind == DK_WARNING
> > +                   || diagnostic->kind == DK_PEDWARN);
> > +  if (was_warning && context->dc_inhibit_warnings)
> > +    return false;
> >
> >     if (diagnostic->kind == DK_PEDWARN)
> >       {
> > @@ -1537,9 +1521,12 @@ diagnostic_report_diagnostic (diagnostic_context *context,
> >     if (!diagnostic_enabled (context, diagnostic))
> >       return false;
> >
> > -  if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
> > -    /* Bail if the warning is not to be reported because all locations
> > -       in the inlining stack (if there is one) are in system headers.  */
> > +  if ((was_warning || diagnostic->kind == DK_WARNING)
> > +      && ((!context->dc_warn_system_headers
> > +        && diagnostic->m_iinfo.m_allsyslocs)
> > +       || context->dc_inhibit_warnings))
> > +    /* Bail if the warning is not to be reported because all locations in the
> > +       inlining stack (if there is one) are in system headers.  */
> >       return false;
> >
> >     if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
> > @@ -1733,7 +1720,8 @@ diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
> >       {
> >         diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
> >                          permissive_error_kind (global_dc));
> > -      diagnostic.option_index = permissive_error_option (global_dc);
> > +      diagnostic.option_index = (opt != -1 ? opt
> > +                              : permissive_error_option (global_dc));
> >       }
> >     else
> >       {
> > @@ -2029,6 +2017,37 @@ permerror (rich_location *richloc, const char *gmsgid, ...)
> >     return ret;
> >   }
> >
> > +/* Similar to the above, but controlled by a flag other than -fpermissive.
> > +   As above, an error by default or a warning with -fpermissive, but this
> > +   diagnostic can also be downgraded by -Wno-error=opt.  */
> > +
> > +bool
> > +permerror (location_t location, int opt, const char *gmsgid, ...)
> > +{
> > +  auto_diagnostic_group d;
> > +  va_list ap;
> > +  va_start (ap, gmsgid);
> > +  rich_location richloc (line_table, location);
> > +  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PERMERROR);
> > +  va_end (ap);
> > +  return ret;
> > +}
> > +
> > +/* Same as "permerror" above, but at RICHLOC.  */
> > +
> > +bool
> > +permerror (rich_location *richloc, int opt, const char *gmsgid, ...)
> > +{
> > +  gcc_assert (richloc);
> > +
> > +  auto_diagnostic_group d;
> > +  va_list ap;
> > +  va_start (ap, gmsgid);
> > +  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PERMERROR);
> > +  va_end (ap);
> > +  return ret;
> > +}
> > +
> >   /* A hard error: the code is definitely ill-formed, and an object file
> >      will not be produced.  */
> >   void
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
> > new file mode 100644
> > index 00000000000..7d3bca9f231
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
> > @@ -0,0 +1,4 @@
> > +// { dg-do compile { target c++11 } }
> > +
> > +// { dg-error "narrowing" "" { target *-*-* } 2 }
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
> > new file mode 100644
> > index 00000000000..58cdaf273c9
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-additional-options "-w" }
> > +
> > +// { dg-error "narrowing" "" { target *-*-* } 2 }
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
> > new file mode 100644
> > index 00000000000..8528f5d357b
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-additional-options "-Wno-error" }
> > +
> > +// { dg-error "narrowing" "" { target *-*-* } 2 }
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
> > new file mode 100644
> > index 00000000000..1243eb00eef
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-additional-options "-Wno-error=narrowing" }
> > +
> > +// No diagnostic.
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
> > new file mode 100644
> > index 00000000000..0653df9c238
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-options "-fpermissive" }
> > +
> > +// No diagnostic.
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
> > new file mode 100644
> > index 00000000000..d2198298e7c
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-options "-fpermissive -Wsystem-headers" }
> > +
> > +// { dg-warning "narrowing" "" { target *-*-* } 2 }
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
> > new file mode 100644
> > index 00000000000..28f7fe2e84c
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-options "-Wno-narrowing" }
> > +
> > +// No diagnostic
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
> > new file mode 100644
> > index 00000000000..d052beab031
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
> > @@ -0,0 +1,5 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-options "-Wno-error=narrowing -Wsystem-headers" }
> > +
> > +// { dg-warning "narrowing" "" { target *-*-* } 2 }
> > +#include "sys-narrow.h"
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
> > new file mode 100644
> > index 00000000000..e96ee1fc134
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
> > @@ -0,0 +1,6 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-options "-Wno-error=narrowing -w" }
> > +
> > +// No diagnostic
> > +int i = { 2.4 }; // C++11 error: narrowing conversion
> > +
> > diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
> > new file mode 100644
> > index 00000000000..f7d958548cf
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
> > @@ -0,0 +1,6 @@
> > +// { dg-do compile { target c++11 } }
> > +// { dg-options "-fpermissive -w" }
> > +
> > +// No diagnostic
> > +int i = { 2.4 }; // C++11 error: narrowing conversion
> > +
> > diff --git a/gcc/testsuite/g++.dg/ext/integer-pack2.C b/gcc/testsuite/g++.dg/ext/integer-pack2.C
> > index 406e195574c..fa6a8813368 100644
> > --- a/gcc/testsuite/g++.dg/ext/integer-pack2.C
> > +++ b/gcc/testsuite/g++.dg/ext/integer-pack2.C
> > @@ -1,5 +1,5 @@
> >   // { dg-do compile { target { c++11 && int32 } } }
> > -// { dg-options -w }
> > +// { dg-options "-fpermissive -w" }
> >
> >   template<typename T, T...> struct integer_sequence { };
> >   template<typename T, T num>
> >
> > base-commit: 41d1c9a97953b457146c1dbeea2a4f19bfbb0b6e
>
diff mbox series

Patch

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4085fc90907..6b6506a75b2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -231,7 +231,7 @@  in the following sections.
 -fnew-inheriting-ctors
 -fnew-ttp-matching
 -fno-nonansi-builtins  -fnothrow-opt  -fno-operator-names
--fno-optional-diags  -fpermissive
+-fno-optional-diags
 -fno-pretty-templates
 -fno-rtti  -fsized-deallocation
 -ftemplate-backtrace-limit=@var{n}
@@ -323,7 +323,7 @@  Objective-C and Objective-C++ Dialects}.
 @item Warning Options
 @xref{Warning Options,,Options to Request or Suppress Warnings}.
 @gccoptlist{-fsyntax-only  -fmax-errors=@var{n}  -Wpedantic
--pedantic-errors
+-pedantic-errors -fpermissive
 -w  -Wextra  -Wall  -Wabi=@var{n}
 -Waddress  -Wno-address-of-packed-member  -Waggregate-return
 -Walloc-size-larger-than=@var{byte-size}  -Walloc-zero
@@ -3494,12 +3494,6 @@  Disable diagnostics that the standard says a compiler does not need to
 issue.  Currently, the only such diagnostic issued by G++ is the one for
 a name having multiple meanings within a class.
 
-@opindex fpermissive
-@item -fpermissive
-Downgrade some diagnostics about nonconformant code from errors to
-warnings.  Thus, using @option{-fpermissive} allows some
-nonconforming code to compile.
-
 @opindex fno-pretty-templates
 @opindex fpretty-templates
 @item -fno-pretty-templates
@@ -6159,6 +6153,18 @@  errors by @option{-pedantic-errors}.  For instance:
 -Wwrite-strings @r{(C++11 or later)}
 }
 
+@opindex fpermissive
+@item -fpermissive
+Downgrade some required diagnostics about nonconformant code from
+errors to warnings.  Thus, using @option{-fpermissive} allows some
+nonconforming code to compile.  Some C++ diagnostics are controlled
+only by this flag, but it also downgrades some diagnostics that have
+their own flag:
+
+@gccoptlist{
+-Wnarrowing @r{(C++)}
+}
+
 @opindex Wall
 @opindex Wno-all
 @item -Wall
diff --git a/gcc/diagnostic-core.h b/gcc/diagnostic-core.h
index c9e27fd2e6e..2d9909f18bd 100644
--- a/gcc/diagnostic-core.h
+++ b/gcc/diagnostic-core.h
@@ -105,6 +105,9 @@  extern bool pedwarn (rich_location *, int, const char *, ...)
 extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern bool permerror (rich_location *, const char *,
 				   ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern bool permerror (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
+extern bool permerror (rich_location *, int, const char *,
+		       ...) ATTRIBUTE_GCC_DIAG(3,4);
 extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
 extern void sorry_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
 extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h b/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
new file mode 100644
index 00000000000..ff042c54a10
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow.h
@@ -0,0 +1,2 @@ 
+#pragma GCC system_header
+int i = { 2.4 }; // C++11 error: narrowing conversion
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index cd1ea045720..ab819d4e49d 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -1109,15 +1109,11 @@  check_narrowing (tree type, tree init, tsubst_flags_t complain,
       else if (complain & tf_error)
 	{
 	  int savederrorcount = errorcount;
-	  if (!flag_permissive)
-	    global_dc->pedantic_errors = 1;
-	  auto s = make_temp_override (global_dc->dc_warn_system_headers, true);
-	  pedwarn (loc, OPT_Wnarrowing,
-		   "narrowing conversion of %qE from %qH to %qI",
-		   init, ftype, type);
+	  permerror (loc, OPT_Wnarrowing,
+		     "narrowing conversion of %qE from %qH to %qI",
+		     init, ftype, type);
 	  if (errorcount == savederrorcount)
 	    ok = true;
-	  global_dc->pedantic_errors = flag_pedantic_errors;
 	}
     }
 
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 65a78840a66..fcbd69f2b8b 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -1232,14 +1232,6 @@  static diagnostic_t
 update_effective_level_from_pragmas (diagnostic_context *context,
 				     diagnostic_info *diagnostic)
 {
-  if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
-    {
-      /* Ignore the diagnostic if all the inlined locations are
-	 in system headers and -Wno-system-headers is in effect.  */
-      diagnostic->kind = DK_IGNORED;
-      return DK_IGNORED;
-    }
-
   if (context->n_classification_history <= 0)
     return DK_UNSPECIFIED;
 
@@ -1480,24 +1472,16 @@  bool
 diagnostic_report_diagnostic (diagnostic_context *context,
 			      diagnostic_info *diagnostic)
 {
-  location_t location = diagnostic_location (diagnostic);
   diagnostic_t orig_diag_kind = diagnostic->kind;
 
   gcc_assert (context->m_output_format);
 
   /* Give preference to being able to inhibit warnings, before they
      get reclassified to something else.  */
-  bool report_warning_p = true;
-  if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
-    {
-      if (context->dc_inhibit_warnings)
-	return false;
-      /* Remember the result of the overall system header warning setting
-	 but proceed to also check the inlining context.  */
-      report_warning_p = diagnostic_report_warnings_p (context, location);
-      if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
-	return false;
-    }
+  bool was_warning = (diagnostic->kind == DK_WARNING
+		      || diagnostic->kind == DK_PEDWARN);
+  if (was_warning && context->dc_inhibit_warnings)
+    return false;
 
   if (diagnostic->kind == DK_PEDWARN)
     {
@@ -1537,9 +1521,12 @@  diagnostic_report_diagnostic (diagnostic_context *context,
   if (!diagnostic_enabled (context, diagnostic))
     return false;
 
-  if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
-    /* Bail if the warning is not to be reported because all locations
-       in the inlining stack (if there is one) are in system headers.  */
+  if ((was_warning || diagnostic->kind == DK_WARNING)
+      && ((!context->dc_warn_system_headers
+	   && diagnostic->m_iinfo.m_allsyslocs)
+	  || context->dc_inhibit_warnings))
+    /* Bail if the warning is not to be reported because all locations in the
+       inlining stack (if there is one) are in system headers.  */
     return false;
 
   if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
@@ -1733,7 +1720,8 @@  diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
     {
       diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
 			   permissive_error_kind (global_dc));
-      diagnostic.option_index = permissive_error_option (global_dc);
+      diagnostic.option_index = (opt != -1 ? opt
+				 : permissive_error_option (global_dc));
     }
   else
     {
@@ -2029,6 +2017,37 @@  permerror (rich_location *richloc, const char *gmsgid, ...)
   return ret;
 }
 
+/* Similar to the above, but controlled by a flag other than -fpermissive.
+   As above, an error by default or a warning with -fpermissive, but this
+   diagnostic can also be downgraded by -Wno-error=opt.  */
+
+bool
+permerror (location_t location, int opt, const char *gmsgid, ...)
+{
+  auto_diagnostic_group d;
+  va_list ap;
+  va_start (ap, gmsgid);
+  rich_location richloc (line_table, location);
+  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PERMERROR);
+  va_end (ap);
+  return ret;
+}
+
+/* Same as "permerror" above, but at RICHLOC.  */
+
+bool
+permerror (rich_location *richloc, int opt, const char *gmsgid, ...)
+{
+  gcc_assert (richloc);
+
+  auto_diagnostic_group d;
+  va_list ap;
+  va_start (ap, gmsgid);
+  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PERMERROR);
+  va_end (ap);
+  return ret;
+}
+
 /* A hard error: the code is definitely ill-formed, and an object file
    will not be produced.  */
 void
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
new file mode 100644
index 00000000000..7d3bca9f231
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1.C
@@ -0,0 +1,4 @@ 
+// { dg-do compile { target c++11 } }
+
+// { dg-error "narrowing" "" { target *-*-* } 2 }
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
new file mode 100644
index 00000000000..58cdaf273c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1a.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-w" }
+
+// { dg-error "narrowing" "" { target *-*-* } 2 }
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
new file mode 100644
index 00000000000..8528f5d357b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1b.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-error" }
+
+// { dg-error "narrowing" "" { target *-*-* } 2 }
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
new file mode 100644
index 00000000000..1243eb00eef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1c.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-error=narrowing" }
+
+// No diagnostic.
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
new file mode 100644
index 00000000000..0653df9c238
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1d.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-fpermissive" }
+
+// No diagnostic.
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
new file mode 100644
index 00000000000..d2198298e7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1e.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-fpermissive -Wsystem-headers" }
+
+// { dg-warning "narrowing" "" { target *-*-* } 2 }
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
new file mode 100644
index 00000000000..28f7fe2e84c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1f.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-narrowing" }
+
+// No diagnostic
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
new file mode 100644
index 00000000000..d052beab031
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1g.C
@@ -0,0 +1,5 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-error=narrowing -Wsystem-headers" }
+
+// { dg-warning "narrowing" "" { target *-*-* } 2 }
+#include "sys-narrow.h"
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
new file mode 100644
index 00000000000..e96ee1fc134
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1h.C
@@ -0,0 +1,6 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-error=narrowing -w" }
+
+// No diagnostic
+int i = { 2.4 }; // C++11 error: narrowing conversion
+
diff --git a/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
new file mode 100644
index 00000000000..f7d958548cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/sys-narrow1i.C
@@ -0,0 +1,6 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-fpermissive -w" }
+
+// No diagnostic
+int i = { 2.4 }; // C++11 error: narrowing conversion
+
diff --git a/gcc/testsuite/g++.dg/ext/integer-pack2.C b/gcc/testsuite/g++.dg/ext/integer-pack2.C
index 406e195574c..fa6a8813368 100644
--- a/gcc/testsuite/g++.dg/ext/integer-pack2.C
+++ b/gcc/testsuite/g++.dg/ext/integer-pack2.C
@@ -1,5 +1,5 @@ 
 // { dg-do compile { target { c++11 && int32 } } }
-// { dg-options -w }
+// { dg-options "-fpermissive -w" }
 
 template<typename T, T...> struct integer_sequence { };
 template<typename T, T num>