/* Calculate the common logarithm of arg. We use the natural
- logaritm of arg and of 10:
+ logarithm of arg and of 10:
log10(arg) = log(arg)/log(10) */
/* Make sure a constant numeric expression is within the range for
- its type and kind. Note that there's also a gfc_check_range(),
+ its type and kind. GMP is doing 130 bit arithmetic, so an UNDERFLOW
+ is numerically zero for REAL(4) and REAL(8) types. Reset the value(s)
+ to exactly 0 for UNDERFLOW. Note that there's also a gfc_check_range(),
but that one deals with the intrinsic RANGE function. */
arith
case BT_REAL:
rc = gfc_check_real_range (e->value.real, e->ts.kind);
+ if (rc == ARITH_UNDERFLOW)
+ mpf_set_ui (e->value.real, 0);
break;
case BT_COMPLEX:
rc = gfc_check_real_range (e->value.complex.r, e->ts.kind);
- if (rc == ARITH_OK)
- rc = gfc_check_real_range (e->value.complex.i, e->ts.kind);
+ if (rc == ARITH_UNDERFLOW)
+ mpf_set_ui (e->value.real, 0);
+ if (rc == ARITH_OK || rc == ARITH_UNDERFLOW)
+ {
+ rc = gfc_check_real_range (e->value.complex.i, e->ts.kind);
+ if (rc == ARITH_UNDERFLOW)
+ mpf_set_ui (e->value.real, 0);
+ }
break;
rc = gfc_range_check (result);
- if (rc != ARITH_OK)
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else if (rc != ARITH_OK)
gfc_free_expr (result);
else
*resultp = result;
rc = gfc_range_check (result);
- if (rc != ARITH_OK)
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else if (rc != ARITH_OK)
gfc_free_expr (result);
else
*resultp = result;
rc = gfc_range_check (result);
- if (rc != ARITH_OK)
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else if (rc != ARITH_OK)
gfc_free_expr (result);
else
*resultp = result;
rc = gfc_range_check (result);
- if (rc != ARITH_OK)
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else if (rc != ARITH_OK)
gfc_free_expr (result);
else
*resultp = result;
if (rc == ARITH_OK)
rc = gfc_range_check (result);
- if (rc != ARITH_OK)
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else if (rc != ARITH_OK)
gfc_free_expr (result);
else
*resultp = result;
if (rc == ARITH_OK)
rc = gfc_range_check (result);
- if (rc != ARITH_OK)
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &op1->where);
+ rc = ARITH_OK;
+ *resultp = result;
+ }
+ else if (rc != ARITH_OK)
gfc_free_expr (result);
else
*resultp = result;
gfc_error ("%s converting %s to %s at %L", gfc_arith_error (rc),
gfc_typename (from), gfc_typename (to), where);
- /* TODO: Do something about the error, ie underflow rounds to 0,
- throw exception, return NaN, etc. */
+ /* TODO: Do something about the error, ie, throw exception, return
+ NaN, etc. */
}
/* Convert integers to integers. */
mpf_set (result->value.real, src->value.real);
- if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK)
+ rc = gfc_check_real_range (result->value.real, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.real, 0);
+ }
+ else if (rc != ARITH_OK)
{
arith_error (rc, &src->ts, &result->ts, &src->where);
gfc_free_expr (result);
mpf_set (result->value.complex.r, src->value.real);
mpf_set_ui (result->value.complex.i, 0);
- if ((rc = gfc_check_real_range (result->value.complex.r, kind)) != ARITH_OK)
+ rc = gfc_check_real_range (result->value.complex.r, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.complex.r, 0);
+ }
+ else if (rc != ARITH_OK)
{
arith_error (rc, &src->ts, &result->ts, &src->where);
gfc_free_expr (result);
mpf_set (result->value.real, src->value.complex.r);
- if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK)
+ rc = gfc_check_real_range (result->value.real, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.real, 0);
+ }
+ if (rc != ARITH_OK)
{
arith_error (rc, &src->ts, &result->ts, &src->where);
gfc_free_expr (result);
mpf_set (result->value.complex.r, src->value.complex.r);
mpf_set (result->value.complex.i, src->value.complex.i);
- if ((rc = gfc_check_real_range (result->value.complex.r, kind)) != ARITH_OK
- || (rc =
- gfc_check_real_range (result->value.complex.i, kind)) != ARITH_OK)
+ rc = gfc_check_real_range (result->value.complex.r, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.complex.r, 0);
+ }
+ else if (rc != ARITH_OK)
+ {
+ arith_error (rc, &src->ts, &result->ts, &src->where);
+ gfc_free_expr (result);
+ return NULL;
+ }
+
+ rc = gfc_check_real_range (result->value.complex.i, kind);
+
+ if (rc == ARITH_UNDERFLOW)
+ {
+ if (gfc_option.warn_underflow)
+ gfc_warning ("%s at %L", gfc_arith_error (rc), &src->where);
+ mpf_set_ui(result->value.complex.i, 0);
+ }
+ else if (rc != ARITH_OK)
{
arith_error (rc, &src->ts, &result->ts, &src->where);
gfc_free_expr (result);
@gccoptlist{
-fsyntax-only -pedantic -pedantic-errors @gol
-w -Wall -Waliasing -Wconversion @gol
--Wimplicit-interface -Wsurprising -Wunused-labels @gol
+-Wimplicit-interface -Wsurprising -Wunderflow -Wunused-labels @gol
-Wline-truncation @gol
-Werror -W}
Specify the maximum allowed identifier length. Typical values are
31 (Fortran 95) and 63 (Fortran 200x).
-@cindex -fimpicit-none option
+@cindex -fimplicit-none option
@cindex options, -fimplicit-none
@item -fimplicit-none
Specify that no implicit typing is allowed, unless overridden by explicit
@cindex warnings, all
Enables commonly used warning options that which pertain to usage that
we recommend avoiding and that we believe is easy to avoid.
-This currenly includes @option{-Wunused-labels}, @option{-Waliasing},
+This currently includes @option{-Wunused-labels}, @option{-Waliasing},
@option{-Wsurprising} and @option{-Wline-truncation}.
@item -Waliasing
@cindex aliasing
Warn about possible aliasing of dummy arguments. The following example
-witll trigger teh warhing as it would be illegal to @code{bar} to
+will trigger the warning as it would be illegal to @code{bar} to
modify either parameter.
@smallexample
INTEGER A
@cindex options, -Wsurprising
@item -Wsurprising
@cindex Suspicious
-Produce a warning when ``suspicous'' code constructs are encountered.
-While techically legal these usually indicate that an error has been made.
+Produce a warning when ``suspicious'' code constructs are encountered.
+While technically legal these usually indicate that an error has been made.
This currently produces a warning under the following circumstances:
A LOGICAL SELECT construct has three CASE statements.
@end itemize
+@cindex -Wunderflow
+@cindex options, -Wunderflow
+@item -Wunderflow
+@cindex UNDERFLOW
+Produce a warning when numerical constant expressions are
+encountered, which yield an UNDERFLOW during compilation.
+
+
@cindex -Wunused-labels option
@cindex options, -Wunused-labels
@item -Wunused-labels
@cindex option, -fdump-parse-tree
@item -fdump-parse-tree
Output the internal parse tree before starting code generation. Only
-really usedful for debugging gfortran itself.
+really useful for debugging gfortran itself.
@end table
@xref{Debugging Options,,Options for Debugging Your Program or GCC,
for previously compiled modules.
It also affects the search paths used by @command{cpp} when used to preprocess
-fortran source.
+Fortran source.
@table @gcctabopt
@cindex -Idir option
@cindex option, -Mdir
@item -M@var{dir}
@item -J@var{dir}
-This option specifies where to put @samp{.mod} files for compiled modiles.
-It is also added to the list of directories to searhed by an @code{USE}
+This option specifies where to put @samp{.mod} files for compiled modules.
+It is also added to the list of directories to searched by an @code{USE}
statement.
The default is the current directory.
checks array indices for assumed and deferred
shape arrays against the actual allocated bounds.
-In the future this may also include other forms of checking, eg. checing
+In the future this may also include other forms of checking, eg. checking
substring references.
@item -fpackderived
@cindex Structure packing
This option tells gfortran to pack derived type members as closely as
-possible. Code compiled with this option is likley to be incompatible
+possible. Code compiled with this option is likely to be incompatible
with code compiled without this option, and may execute slower.
@cindex -frepack-arrays option