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
Created attachment 12140 [details] Sample RESHAPE with missed array bounds violation
I'll note that the Portland, Intel and g95 compilers do not see this issue either. SunStudio does, at runtime.
(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".
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
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.
> 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"
$ 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.