Bug 28849 - Missed array shape violation with RESHAPE despite -fbounds-check
Summary: Missed array shape violation with RESHAPE despite -fbounds-check
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Fortran_bounds_checking
  Show dependency treegraph
 
Reported: 2006-08-25 20:39 UTC by Harald Anlauf
Modified: 2009-04-04 18:29 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.3.3
Known to fail:
Last reconfirmed: 2006-10-02 11:54:18


Attachments
Sample RESHAPE with missed array bounds violation (316 bytes, text/plain)
2006-08-25 20:40 UTC, Harald Anlauf
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Harald Anlauf 2006-08-25 20:39:24 UTC
The assignment of a RESHAPE()d array does not trigger
a run-time error with bounds-checking turned on.

% gfortran -O0 -g -fbounds-check gfcbug39_bounds_check.f90 && ./a.out
 Assignments with correct shapes after RESHAPE...
 a(:,1) =   1.000000    
 b(:,1) =   1.000000       2.000000    
 ...and with wrong shape (should fail with bounds checking on)
 a(:,1) =   1.000000    
 b(:,1) =   1.000000       2.000000    
 Must have missed an array bound violation after RESHAPE...


See the attached sample program for details.

Cheers,
-ha
Comment 1 Harald Anlauf 2006-08-25 20:40:56 UTC
Created attachment 12140 [details]
Sample RESHAPE with missed array bounds violation
Comment 2 Francois-Xavier Coudert 2006-10-11 13:17:42 UTC
I'll note that the Portland, Intel and g95 compilers do not see this issue either. SunStudio does, at runtime.
Comment 3 Harald Anlauf 2006-10-11 13:58:26 UTC
(In reply to comment #2)
> I'll note that the Portland, Intel and g95 compilers do not see this issue
> either.

Well, I get a bounds violation with current versions of g95 (0.91)
on both Linux and Cygwin:

% g95 -g -fbounds-check -ftrace=full gfcbug39_bounds_check.f90 && ./a.out 
 Assignments with correct shapes after RESHAPE...
 a(:,1) = 1.
 b(:,1) = 1. 2.
 ...and with wrong shape (should fail with bounds checking on)
At line 17 of file gfcbug39_bounds_check.f90
Traceback: not available, compile with -ftrace=frame or -ftrace=full
Fortran runtime error: Array element out of bounds: 2 in (1:1), dim=2


With xlf 9.1 on AIX:

% xlf95 -qsuffix=f=f90 -C -g gfcbug39_bounds_check.f90
% dbx a.out 
Type 'help' for help.
reading symbolic information ...
(dbx) run
 Assignments with correct shapes after RESHAPE...
 a(:,1) = 1.000000000
 b(:,1) = 1.000000000 2.000000000
 ...and with wrong shape (should fail with bounds checking on)

Trace/BPT trap in gfc_bounds_check at line 17
   17     a(:,:) = reshape (v(:), (/ 2, 1 /) )
(dbx) 


With Intel I had a discussion about this, as ifc7 reports
a shape violation, and ifort8 and ifort9 do not.  Intel
does not consider this a regression, and think that
reimplementing the old behavior in 8.x and 9.x would be
an "enhancement".
Comment 4 Tobias Burnus 2006-11-08 19:44:33 UTC
See also PR 29572 (matmul(a,b) and matmul(a,transpose(b))).

sunf95 and NAG f95 catch this PR and also PR29572 and also pack().
g95 catches this PR and matmul(a,b), but not matmul(a,transpose(b))).
ifort 9.1 (and 10.0) don't implement these kinds of checks.

For pack, see:
http://gcc.gnu.org/ml/fortran/2006-11/msg00243.html

I think there are two possible solutions:
Specific checks for known functions (reshape, matmul etc.), which is seemingly what g95 does.
Or a solution for general functions, which seems to be what NAG f95/sunf95 do.

For the latter, a test case is (imagine also pointer, allocatable, in different modules etc.):
program check
  implicit none
  real, dimension(2) :: r
  r = foo(5)
contains
  function foo(n)
    integer :: n
    real, dimension(n) :: foo
    foo = 42.0
  end function foo
end program check
Comment 5 Tobias Burnus 2006-11-08 20:08:39 UTC
Postscriptum:
sunf95 already finds the problem in the program "check" at compile time.

For non-intrinsics (non libgfortran) routines, one way to do it is too do it in the function called. (Internally called as  foo (&parm.5, D.1358);)
That way one could even detect the problem if one moves the "foo" function out of the "program" and uses an "interface". In this case neither sunf95 nor NAGf95 find the error.

But what would be the best way for the library? Adding a check version to it? Adding a if(flag) to it (may slow down)? Both NAG f95 and sunf95 seem to expand those intrinsics (pack, reshape, transpose) rather than using a library call and add then the check directly in the tree.
Comment 6 Tobias Burnus 2006-11-08 20:48:49 UTC
> In this case neither sunf95 nor NAGf95 find the error.
This is actually wrong; both find it.

In my example the original tree looks like (shortend): foo (__result, n)
    ubound.0 = (int8) *n;
      S.4 = 1;
      while (1)
        {
          if (S.4 > ubound.0) goto L.1; else (void) 0;
          (*__result.0)[NON_LVALUE_EXPR <S.4> * D.1347 + D.1345] = 4.2e+1;
          S.4 = S.4 + 1;
        }
      L.1:;
Thus one should check
   "ubound.0*stride.1+offset.2 > __result->dim[0].ubound"
and
   "1 *stride.1+offset.2 < __result->dim[0].lbound"
Comment 7 Daniel Franke 2009-04-04 18:29:58 UTC
$ gfortran-4.3.3 -Wall -g -W -fbounds-check pr28849.f90 && ./a.out
 Assignments with correct shapes after RESHAPE...
 a(:,1) =   1.0000000
 b(:,1) =   1.0000000       2.0000000
 ...and with wrong shape (should fail with bounds checking on)
Fortran runtime error: Incorrect extent in return value of RESHAPE intrinsic in dimension 1: is 1, should be 2

Same for 4.4.0 and 4.5.0.
Closing. Please reopen if anything else is left.