diff options
Diffstat (limited to 'libgfortran/runtime')
-rw-r--r-- | libgfortran/runtime/compile_options.c | 3 | ||||
-rw-r--r-- | libgfortran/runtime/stop.c | 54 |
2 files changed, 57 insertions, 0 deletions
diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index a49514c0aa9..1416d6634f4 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -173,6 +173,8 @@ set_options (int num, int options[]) the library behavior; range checking is now always done when parsing integers. It's place in the options array is retained due to ABI compatibility. Remove when bumping the library ABI. */ + if (num >= 9) + compile_options.fpe_summary = options[8]; /* If backtrace is required, we set signal handlers on the POSIX 2001 signals with core action. */ @@ -225,6 +227,7 @@ init_compile_options (void) compile_options.pedantic = 0; compile_options.backtrace = 0; compile_options.sign_zero = 1; + compile_options.fpe_summary = 0; } /* Function called by the front-end to tell us the diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c index 4805412e761..1091245241a 100644 --- a/libgfortran/runtime/stop.c +++ b/libgfortran/runtime/stop.c @@ -32,6 +32,55 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif +/* Fortran 2008 demands: If any exception (14) is signaling on that image, the + processor shall issue a warning indicating which exceptions are signaling; + this warning shall be on the unit identified by the named constant + ERROR_UNIT (13.8.2.8). In line with other compilers, we do not report + inexact - and we optionally ignore underflow, cf. thread starting at + http://mailman.j3-fortran.org/pipermail/j3/2013-June/006452.html. */ + +static void +report_exception (void) +{ + int set_excepts; + + if (!compile_options.fpe_summary) + return; + + set_excepts = get_fpu_except_flags (); + if ((set_excepts & compile_options.fpe_summary) == 0) + return; + + estr_write ("Note: The following floating-point exceptions are signalling:"); + + if ((compile_options.fpe_summary & GFC_FPE_INVALID) + && (set_excepts & GFC_FPE_INVALID)) + estr_write (" IEEE_INVALID_FLAG"); + + if ((compile_options.fpe_summary & GFC_FPE_ZERO) + && (set_excepts & GFC_FPE_ZERO)) + estr_write (" IEEE_DIVIDE_BY_ZERO"); + + if ((compile_options.fpe_summary & GFC_FPE_OVERFLOW) + && (set_excepts & GFC_FPE_OVERFLOW)) + estr_write (" IEEE_OVERFLOW_FLAG"); + + if ((compile_options.fpe_summary & GFC_FPE_UNDERFLOW) + && (set_excepts & GFC_FPE_UNDERFLOW)) + estr_write (" IEEE_UNDERFLOW_FLAG"); + + if ((compile_options.fpe_summary & GFC_FPE_DENORMAL) + && (set_excepts & GFC_FPE_DENORMAL)) + estr_write (" IEEE_DENORMAL"); + + if ((compile_options.fpe_summary & GFC_FPE_INEXACT) + && (set_excepts & GFC_FPE_INEXACT)) + estr_write (" IEEE_INEXACT_FLAG"); + + estr_write ("\n"); +} + + /* A numeric STOP statement. */ extern void stop_numeric (GFC_INTEGER_4) @@ -41,6 +90,7 @@ export_proto(stop_numeric); void stop_numeric (GFC_INTEGER_4 code) { + report_exception (); if (code == -1) code = 0; else @@ -59,6 +109,7 @@ export_proto(stop_numeric_f08); void stop_numeric_f08 (GFC_INTEGER_4 code) { + report_exception (); st_printf ("STOP %d\n", (int)code); exit (code); } @@ -69,6 +120,7 @@ stop_numeric_f08 (GFC_INTEGER_4 code) void stop_string (const char *string, GFC_INTEGER_4 len) { + report_exception (); if (string) { estr_write ("STOP "); @@ -91,6 +143,7 @@ export_proto(error_stop_string); void error_stop_string (const char *string, GFC_INTEGER_4 len) { + report_exception (); estr_write ("ERROR STOP "); (void) write (STDERR_FILENO, string, len); estr_write ("\n"); @@ -108,6 +161,7 @@ export_proto(error_stop_numeric); void error_stop_numeric (GFC_INTEGER_4 code) { + report_exception (); st_printf ("ERROR STOP %d\n", (int) code); exit (code); } |