summaryrefslogtreecommitdiff
path: root/gcc/fortran/error.c
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2014-12-03 17:50:06 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2014-12-03 17:50:06 +0000
commit48749dbcc461753861059d1fc48c40d2e0aefaa2 (patch)
treeffa63d8c289a7c4e01689478d728abff9b4c33ab /gcc/fortran/error.c
parentd6d34aa9133afdee0ca74b354a72cb720f431c1a (diff)
downloadgcc-48749dbcc461753861059d1fc48c40d2e0aefaa2.tar.gz
re PR fortran/44054 (Handle -Werror, -Werror=, -fdiagnostics-show-option, !GCC$ diagnostic (pragmas) and color)
gcc/testsuite/ChangeLog: 2014-12-03 Manuel López-Ibáñez <manu@gcc.gnu.org> PR fortran/44054 * gfortran.dg/warnings_are_errors_1.f90: Update warnings to errors. * gfortran.dg/warnings_are_errors_1.f: Likewise. gcc/fortran/ChangeLog: 2014-12-03 Manuel López-Ibáñez <manu@gcc.gnu.org> PR fortran/44054 * gfortran.h (gfc_warning): Now returns bool. Add overload that accepts opt. (gfc_warning_1): Declare. * error.c (pp_warning_buffer,warningcount_buffered,werrorcount_buffered): New. (gfc_buffer_error): Set pp_warning_buffer.flush_p. (gfc_clear_pp_buffer): New. (gfc_warning_1): Renamed from gfc_warning. (gfc_warning): Add three new overloads. One that takes just a format string and ellipsis, another that takes also a warning option, and another that takes also va_list instead of ellipsis. (gfc_clear_warning): Clear pp_warning_buffer. (gfc_warning_check): Flush pp_warning_buffer and update warning and werror counters. (gfc_diagnostics_init): Init pp_warning_buffer. * Update all gfc_warning calls that do not multiple locations to use %qs and OPT_W*, otherwise use gfc_warning_1. gcc/ChangeLog: 2014-12-03 Manuel López-Ibáñez <manu@gcc.gnu.org> PR fortran/44054 * pretty-print.c (output_buffer::output_buffer): Init flush_p to true. (pp_flush): Flush only if flush_p. (pp_really_flush): New. * pretty-print.h (struct output_buffer): Add flush_p. (pp_really_flush): Declare. From-SVN: r218326
Diffstat (limited to 'gcc/fortran/error.c')
-rw-r--r--gcc/fortran/error.c124
1 files changed, 123 insertions, 1 deletions
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 70429d3e122..d6475f37248 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -50,6 +50,10 @@ static int terminal_width, buffer_flag, errors, warnings;
static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer;
+static output_buffer pp_warning_buffer;
+static int warningcount_buffered, werrorcount_buffered;
+
+#include <new> /* For placement-new */
/* Go one level deeper suppressing errors. */
@@ -122,6 +126,7 @@ void
gfc_buffer_error (int flag)
{
buffer_flag = flag;
+ pp_warning_buffer.flush_p = !flag;
}
@@ -804,10 +809,25 @@ gfc_increment_error_count (void)
}
+/* Clear any output buffered in a pretty-print output_buffer. */
+
+static void
+gfc_clear_pp_buffer (output_buffer *this_buffer)
+{
+ pretty_printer *pp = global_dc->printer;
+ output_buffer *tmp_buffer = pp->buffer;
+ pp->buffer = this_buffer;
+ pp_clear_output_area (pp);
+ pp->buffer = tmp_buffer;
+}
+
+
/* Issue a warning. */
+/* Use gfc_warning instead, unless two locations are used in the same
+ warning or for scanner.c, if the location is not properly set up. */
void
-gfc_warning (const char *gmsgid, ...)
+gfc_warning_1 (const char *gmsgid, ...)
{
va_list argp;
@@ -833,6 +853,88 @@ gfc_warning (const char *gmsgid, ...)
}
+/* This is just a helper function to avoid duplicating the logic of
+ gfc_warning. */
+
+static bool
+gfc_warning (int opt, const char *gmsgid, va_list ap) ATTRIBUTE_GCC_GFC(2,0);
+
+static bool
+gfc_warning (int opt, const char *gmsgid, va_list ap)
+{
+ va_list argp;
+ va_copy (argp, ap);
+
+ diagnostic_info diagnostic;
+ bool fatal_errors = global_dc->fatal_errors;
+ pretty_printer *pp = global_dc->printer;
+ output_buffer *tmp_buffer = pp->buffer;
+ bool buffered_p = !pp_warning_buffer.flush_p;
+
+ gfc_clear_pp_buffer (&pp_warning_buffer);
+
+ if (buffered_p)
+ {
+ pp->buffer = &pp_warning_buffer;
+ global_dc->fatal_errors = false;
+ /* To prevent -fmax-errors= triggering. */
+ --werrorcount;
+ }
+
+ diagnostic_set_info (&diagnostic, gmsgid, &argp, UNKNOWN_LOCATION,
+ DK_WARNING);
+ diagnostic.option_index = opt;
+ bool ret = report_diagnostic (&diagnostic);
+
+ if (buffered_p)
+ {
+ pp->buffer = tmp_buffer;
+ global_dc->fatal_errors = fatal_errors;
+
+ warningcount_buffered = 0;
+ werrorcount_buffered = 0;
+ /* Undo the above --werrorcount if not Werror, otherwise
+ werrorcount is correct already. */
+ if (!ret)
+ ++werrorcount;
+ else if (diagnostic.kind == DK_ERROR)
+ ++werrorcount_buffered;
+ else
+ ++werrorcount, --warningcount, ++warningcount_buffered;
+ }
+
+ va_end (argp);
+ return ret;
+}
+
+/* Issue a warning. */
+/* This function uses the common diagnostics, but does not support
+ two locations; when being used in scanner.c, ensure that the location
+ is properly setup. Otherwise, use gfc_warning_1. */
+
+bool
+gfc_warning (int opt, const char *gmsgid, ...)
+{
+ va_list argp;
+
+ va_start (argp, gmsgid);
+ bool ret = gfc_warning (opt, gmsgid, argp);
+ va_end (argp);
+ return ret;
+}
+
+bool
+gfc_warning (const char *gmsgid, ...)
+{
+ va_list argp;
+
+ va_start (argp, gmsgid);
+ bool ret = gfc_warning (0, gmsgid, argp);
+ va_end (argp);
+ return ret;
+}
+
+
/* Whether, for a feature included in a given standard set (GFC_STD_*),
we should issue an error or a warning, or be quiet. */
@@ -1176,6 +1278,11 @@ void
gfc_clear_warning (void)
{
warning_buffer.flag = 0;
+
+ gfc_clear_pp_buffer (&pp_warning_buffer);
+ warningcount_buffered = 0;
+ werrorcount_buffered = 0;
+ pp_warning_buffer.flush_p = false;
}
@@ -1192,6 +1299,20 @@ gfc_warning_check (void)
fputs (warning_buffer.message, stderr);
warning_buffer.flag = 0;
}
+
+ /* This is for the new diagnostics machinery. */
+ pretty_printer *pp = global_dc->printer;
+ output_buffer *tmp_buffer = pp->buffer;
+ pp->buffer = &pp_warning_buffer;
+ if (pp_last_position_in_text (pp) != NULL)
+ {
+ pp_really_flush (pp);
+ pp_warning_buffer.flush_p = true;
+ warningcount += warningcount_buffered;
+ werrorcount += werrorcount_buffered;
+ }
+
+ pp->buffer = tmp_buffer;
}
@@ -1407,6 +1528,7 @@ gfc_diagnostics_init (void)
diagnostic_finalizer (global_dc) = gfc_diagnostic_finalizer;
diagnostic_format_decoder (global_dc) = gfc_format_decoder;
global_dc->caret_char = '^';
+ new (&pp_warning_buffer) output_buffer ();
}
void