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