This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug fortran/33296] nearest(huge(1.0),1.0) gives an error



------- Comment #4 from dominiq at lps dot ens dot fr  2007-09-07 08:45 -------
> I think the standard is very clear on that. Quoting F2003 13.7:

> "A program is prohibited from invoking an intrinsic procedure under
> circumstances where a value to be returned in a subroutine argument or function
> result is outside the range of values representable by objects of the specified
> type and type parameters, unless the intrinsic module IEEE_ARITHMETIC (section
> 14) is accessible and there is support for an infinite or a NaN result, as 
> appropriate."

> Unless we have IEEE_ARITHMETIC, we should stick to an error.

As usual, the standard put the burden on the user only and does not give any
clue about what should be done with violations.  In my opinion there are three
ways to handle them:

(1) Commit suicide (the code not the user!-): in most (all) situations Inf's
and NaN's are coming from exceptions (for 100% of my codes and with probability
1 for the other ones I use, they comes from bug or (inclusive) numerical
instabilities).  On most platforms these exceptions could be traped to give
errors or runtime abort, as done for the memory violations.  This the way I
would like to see implemented by default, since I think it is the only one
making sense for numerical simulations.
In this case -fno-range-check could be a simple way to disable the traping.

(2) Replace the "and" in "... is accessible and there is support ..." by an
"or".  This is the choice of most (all) compilers I have access to, including
gfortran outside this specific issue: there is a couple codes in the gfortran
testsuite testing for Inf and NaN without -fno-range-check (or at least do not
give errors without it).

(3) Bad ones: half-backed solutions, in which sometines you get (1) and
sometimes (2).  This is the present situation of gfortran, though half is too
good and ~1% would be closer. For instance, the reported case gives an error,
but:

real x
x = huge(1.0)
x = nearest(x,1.0)
end

which is equivalent to the first one, does not give any error even at -O1 and
above:

[karma] f90/bug% gfc -O -fno-range-check -fdump-tree-optimized
test_foverflow_1.f90
[karma] f90/bug% less test_foverflow_1.f90.116t.optimized

;; Function MAIN__ (MAIN__)

Analyzing Edge Insertions.
MAIN__ ()
{
  struct __st_parameter_dt dt_parm.1;
  static int4 options.0[7] = {68, 127, 0, 0, 0, 1, 0};
  real4 x;

<bb 2>:
  _gfortran_set_options (7, &options.0);
  x = 3.40282366920938463463374607431768211456e+38;
  dt_parm.1.common.filename = &"test_foverflow_1.f90"[1]{lb: 1 sz: 1};
  dt_parm.1.common.line = 3;
  dt_parm.1.common.flags = 128;
  dt_parm.1.common.unit = 6;
  _gfortran_st_write (&dt_parm.1);
  _gfortran_transfer_real (&dt_parm.1, &x, 4);
  _gfortran_st_write_done (&dt_parm.1);
  return;

}
[karma] f90/bug% gfc -O -fdump-tree-optimized test_foverflow.f90 <-- present
test
[karma] f90/bug% less test_foverflow.f90.116t.optimized

;; Function MAIN__ (MAIN__)

Analyzing Edge Insertions.
MAIN__ ()
{
  struct __st_parameter_dt dt_parm.1;
  static int4 options.0[7] = {68, 127, 0, 0, 0, 1, 0};
  real4 x;

<bb 2>:
  _gfortran_set_options (7, &options.0);
  x = _gfortran_nearest_r4 (3.4028234663852885981170418348451692544e+38,
1.0e+0);
  dt_parm.1.common.filename = &"test_foverflow.f90"[1]{lb: 1 sz: 1};
  dt_parm.1.common.line = 4;
  dt_parm.1.common.flags = 128;
  dt_parm.1.common.unit = 6;
  _gfortran_st_write (&dt_parm.1);
  _gfortran_transfer_real (&dt_parm.1, &x, 4);
  _gfortran_st_write_done (&dt_parm.1);
  return;

}

BTW is it normal that gfortran_nearest_r4 (3.4...4e+38, 1.0e+0) is not computed
at the optimized level in the second case, while it is done in the first one?
Is this a bug?

To end my "contribution" to this PR, I think a warning with both -std=f* and
-pedantic (thus an error with -pedantic-errors) is already an overkill, but
than an error by default is "user unfriendly" to say the least.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33296


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]