https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120131

--- Comment #6 from kargls at comcast dot net ---
(In reply to Vladimir Terzi from comment #5)
> After a fruitful discussion in Stack Overflow, I understand that the model
> set of integers in Fortran is symmetric about zero according to the formula
> in section 16.4 of https://j3-fortran.org/doc/year/24/24-007.pdf , and,
> therefore, `gfortran` may reject the literal -2147483648 (although it is
> inconvenient and there are no technical reasons to reject it).  But it was
> already known in 2006 that this change will cause "bogus bug reports" (like
> written in https://gcc.gnu.org/legacy-ml/fortran/2006-09/msg00008.html) and
> there are already multiple of such reports on this site.  Then why wasn't
> the error message clarified?

The original error message was

% gfortran14 -o z a.f90
a.f90:1:21:

    1 | print *,  -2147483648
      |                     1
Error: Integer too big for its kind at (1).

Then this commit happen.

2007-08-09  Tobias Burnus  <bur...@net-b.de>

        PR fortran/33001
        * arith.c (arith_error): Point in the error message
        to -fno-range-check.

which gives (with courtesy wrap of a long line)

% gfortran14 -o z a.f90
a.f90:1:21:

    1 | print *,  -2147483648
      |                     1
Error: Integer too big for its kind at (1). This check can be disabled with the
option '-fno-range-check'


Then this commit happen

2007-11-29  Steven G. Kargl  <kar...@comcast.net>

        PR fortran/34230
        * fortran/arith.c (gfc_check_real_range): Set intermediate values
        to +-Inf and 0 when -fno-range-check is in effect.
        * fortran/invoke.texi: Improve -fno-range-check description.

I suppose it is somewhat naive of gfortran contributors to expect that users
read the documentation supplied with the compiler.

‘-fno-range-check’
     Disable range checking on results of simplification of constant
     expressions during compilation.  For example, GNU Fortran gives an
     error at compile time when simplifying ‘a = 1. / 0’.  With this
     option, no error is given and ‘a’ is assigned the value
     ‘+Infinity’.  If an expression evaluates to a value outside of the
     relevant range of [‘-HUGE()’:‘HUGE()’], then the expression is
     replaced by ‘-Inf’ or ‘+Inf’ as appropriate.  Similarly, ‘DATA
     i/Z'FFFFFFFF'/’ results in an integer overflow on most systems, but
     with ‘-fno-range-check’ the value "wraps around" and ‘i’ is
     initialized to -1 instead.

Those last two sentences are important.

Consider the simple example, 

% cat b.f90
   print *, 1 + -1
   end
% gfortran14 -o z b.f90 && ./z
b.f90:1:15:

    1 | print *, 1 + -1
      |               1
Warning: Extension: Unary operator following arithmetic operator (use
parentheses) at (1)
           0
% ~/tmp/root/build/bin/flang -o z b.f90 && ./z
 0

gfortran gives a warning while flang does not; but, it can be forced to tell
you
that the program is invalid

% ~/tmp/root/build/bin/flang -o z -pedantic b.f90 && ./z
./b.f90:1:14: portability: nonstandard usage: signed mult-operand
  print *, 1 + -1
               ^^

% ~/lfortran/work/bin/lfortran -o z b.f90
% ./z
0

There appears to be no option with lfortran to diagnose the invalid code.

Now, returning to a.f90 above.

 gfortran14 -o z a.f90 && ./z
a.f90:1:21:

    1 | print *,  -2147483648
      |                     1
Error: Integer too big for its kind at (1). This check can be disabled with the
option '-fno-range-check'
% gfortran14 -o z -fno-range-check a.f90 && ./z
 -2147483648
% gfortran14 -o z -fno-range-check -pedantic a.f90 && ./z
a.f90:1:21:

    1 | print *,  -2147483648
      |                     1
Warning: Integer outside symmetric range implied by Standard Fortran at (1)
 -2147483648

So, yes, more than one gfortran contributor has thought about the corner
case of -huge(1) - 1.

Reply via email to