The following code gives compile-time warnings that are wrong, and segfaults at runtime: module foo_mod implicit none contains pure function outerprod(a,b) real, intent(in) :: a(:),b(:) real :: outerprod(size(a),size(b)) outerprod = spread(a,dim=2,ncopies=size(b)) * spread(b,dim=1,ncopies=size(a)) end function outerprod end module foo_mod program xouterprod use foo_mod, only: outerprod implicit none integer, parameter :: i = 4, m = 4, n = 4, l = 5 real :: aa(m,i),tempn(n) call random_seed() aa = 1.0 tempn = 2.0 aa(i:m,l:n) = aa(i:m,l:n)+outerprod(aa(i:m,i),tempn(l:n)) ! tricky print*,aa end program xouterprod $ gfortran a.f90 In file a.f90:19 aa(i:m,l:n) = aa(i:m,l:n)+outerprod(aa(i:m,i),tempn(l:n)) ! tricky 1 Warning: Array reference at (1) is out of bounds In file a.f90:19 aa(i:m,l:n) = aa(i:m,l:n)+outerprod(aa(i:m,i),tempn(l:n)) ! tricky 1 Warning: Array reference at (1) is out of bounds In file a.f90:19 aa(i:m,l:n) = aa(i:m,l:n)+outerprod(aa(i:m,i),tempn(l:n)) ! tricky 1 Warning: Array reference at (1) is out of bounds $ ./a.out zsh: segmentation fault ./a.out
A minimal testcase exhibiting both problems (warning and segfault) is: real :: tempn(1) tempn = 2.0 print *, spread(tempn(2:1),dim=1,ncopies=1) end
The problem is in the library. spread_internal rightly understands that the destination array will have zero-size in one dimension, so the call to allocation memory for ret->data at line 104: ret->data = internal_malloc_size (rs * size); gives NULL into ret->data. I don't remember whether we should actually allocate one byte of memory for ret->data, or if we should jut let it be NULL and simply return from the function here.
I believe the segfault is appropriately fixed by the following patch: Index: libgfortran/intrinsics/spread_generic.c =================================================================== --- libgfortran/intrinsics/spread_generic.c (revision 114340) +++ libgfortran/intrinsics/spread_generic.c (working copy) @@ -101,7 +101,14 @@ } } ret->offset = 0; - ret->data = internal_malloc_size (rs * size); + if (rs * size == 0) + { + ret->data = internal_malloc_size (1); + ret->data[0] = 0; + return; + } + else + ret->data = internal_malloc_size (rs * size); } else {
And I'm sure the warnings are appropriately fixed by: Index: resolve.c =================================================================== --- resolve.c (revision 114340) +++ resolve.c (working copy) @@ -2130,11 +2130,24 @@ return FAILURE; } - if (compare_bound (ar->start[i], as->lower[i]) == CMP_LT) - goto bound; - if (compare_bound (ar->start[i], as->upper[i]) == CMP_GT) - goto bound; +#define AR_START (ar->start[i] ? ar->start[i] : as->lower[i]) +#define AR_END (ar->end[i] ? ar->end[i] : as->upper[i]) + if (((compare_bound_int (ar->stride[i], 0) == CMP_GT + || ar->stride[i] == NULL) + && compare_bound (AR_START, AR_END) != CMP_GT) + || (compare_bound_int (ar->stride[i], 0) == CMP_LT + && compare_bound (AR_START, AR_END) != CMP_LT)) + { + if (compare_bound (AR_START, as->lower[i]) == CMP_LT) + goto bound; + if (compare_bound (AR_START, as->upper[i]) == CMP_GT) + goto bound; + +#undef AR_START +#undef AR_END + } + /* TODO: Possibly, we could warn about end[i] being out-of-bound although it is legal (see 6.2.2.3.1). */ But I'm working on expanding this checking according to the TODO, i.e. including checking for the end of the triplet.
Subject: Bug 27895 Author: fxcoudert Date: Mon Jun 5 22:41:29 2006 New Revision: 114414 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=114414 Log: PR libfortran/27895 * resolve.c (compute_last_value_for_triplet): New function. (check_dimension): Correctly handle zero-sized array sections. Add checking on last element of array sections. * gfortran.dg/bounds_check_3.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/bounds_check_3.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog
CSHIFT has the same problem: $ cat zero_cshift.f90 real :: tempn(1) tempn = 2.0 print *, cshift(tempn(2:),shift=1) end $ gfortran zero_cshift.f90 && ./a.out Floating point exception I believe the following functions may not be safe: EOSHIFT, PACK, RESHAPE, TRANSPOSE, UNPACK (and of course, SPREAD and CSHIFT).
Subject: Bug 27895 Author: fxcoudert Date: Tue Jun 20 06:04:14 2006 New Revision: 114803 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=114803 Log: 2006-06-20 Francois-Xavier Coudert <coudert@clipper.ens.fr> PR fortran/27958 * trans-expr.c (gfc_conv_substring): If the substring start is greater than its end, the length of the substring is zero, and not negative. (gfc_trans_string_copy): Don't generate a call to _gfortran_copy_string when destination length is zero. 2006-06-20 Francois-Xavier Coudert <coudert@clipper.ens.fr> PR libfortran/27895 * resolve.c (compute_last_value_for_triplet): New function. (check_dimension): Correctly handle zero-sized array sections. Add checking on last element of array sections. 2006-06-20 Francois-Xavier Coudert <coudert@clipper.ens.fr> * trans.c (gfc_msg_bounds, gfc_msg_fault, gfc_msg_wrong_return): Add strings for common runtime error messages. (gfc_trans_runtime_check): Add a locus argument, use a string and not a string tree for the message. * trans.h (gfc_trans_runtime_check): Change prototype accordingly. (gfc_msg_bounds, gfc_msg_fault, gfc_msg_wrong_return): Add proto. * trans-const.c (gfc_strconst_bounds, gfc_strconst_fault, gfc_strconst_wrong_return, gfc_strconst_current_filename): Remove. (gfc_init_constants): Likewise. * trans-const.h: Likewise. * trans-decl.c (gfc_build_builtin_function_decls): Call to _gfortran_runtime_error has only one argument, the message string. * trans-array.h (gfc_conv_array_ref): Add a symbol argument and a locus. * trans-array.c (gfc_trans_array_bound_check): Build precise error messages. (gfc_conv_array_ref): Use the new symbol argument and the locus to build more precise error messages. (gfc_conv_ss_startstride): More precise error messages. * trans-expr.c (gfc_conv_variable): Give symbol reference and locus to gfc_conv_array_ref. (gfc_conv_function_call): Use the new prototype for gfc_trans_runtime_check. * trans-stmt.c (gfc_trans_goto): Build more precise error message. * trans-io.c (set_string): Likewise. * trans-intrinsic.c (gfc_conv_intrinsic_bound): Use new prototype for gfc_trans_runtime_check. 2006-06-20 Thomas Koenig <Thomas.Koenig@online.de> PR fortran/27715 * arith.c: Cast the characters from the strings to unsigned char to avoid values less than 0 for extended ASCII. 2006-06-20 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/27784 * intrinsics/string_intrinsics.c (compare_string): Use memcmp instead of strncmp to avoid tripping over CHAR(0) in a string. 2006-06-20 Francois-Xavier Coudert <coudert@clipper.ens.fr> PR fortran/27958 * gcc/testsuite/gfortran.dg/substr_2.f: New test. 2006-06-20 Francois-Xavier Coudert <coudert@clipper.ens.fr> PR libfortran/27895 * gfortran.dg/bounds_check_3.f90: New test. 2006-06-20 Thomas Koenig <Thomas.Koenig@online.de> PR fortran/27715 * gfortran.dg/extended_char_comparison_1.f: New test. 2006-06-20 Thomas Koenig <Thomas.Koenig@online.de> PR fortran/27784 * gfortran.dg/string_null_compare_1.f: New test case. Added: branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/bounds_check_3.f90 - copied unchanged from r114414, trunk/gcc/testsuite/gfortran.dg/bounds_check_3.f90 branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f - copied unchanged from r114317, trunk/gcc/testsuite/gfortran.dg/extended_char_comparison_1.f branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/string_null_compare_1.f - copied unchanged from r114175, trunk/gcc/testsuite/gfortran.dg/string_null_compare_1.f branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/substr_2.f - copied unchanged from r114496, trunk/gcc/testsuite/gfortran.dg/substr_2.f Modified: branches/gcc-4_1-branch/gcc/fortran/ChangeLog branches/gcc-4_1-branch/gcc/fortran/arith.c branches/gcc-4_1-branch/gcc/fortran/resolve.c branches/gcc-4_1-branch/gcc/fortran/trans-array.c branches/gcc-4_1-branch/gcc/fortran/trans-array.h branches/gcc-4_1-branch/gcc/fortran/trans-const.c branches/gcc-4_1-branch/gcc/fortran/trans-const.h branches/gcc-4_1-branch/gcc/fortran/trans-decl.c branches/gcc-4_1-branch/gcc/fortran/trans-expr.c branches/gcc-4_1-branch/gcc/fortran/trans-intrinsic.c branches/gcc-4_1-branch/gcc/fortran/trans-io.c branches/gcc-4_1-branch/gcc/fortran/trans-stmt.c branches/gcc-4_1-branch/gcc/fortran/trans.c branches/gcc-4_1-branch/gcc/fortran/trans.h branches/gcc-4_1-branch/gcc/testsuite/ChangeLog branches/gcc-4_1-branch/libgfortran/ChangeLog branches/gcc-4_1-branch/libgfortran/intrinsics/string_intrinsics.c
(In reply to comment #3) > I believe the segfault is appropriately fixed by the following patch I still think this patch is the right thing, and I've been looking through the other transformational function to see which are affected by similar bugs on zero-sized arrays. - SPREAD and CSHIFT are subject to this bug, which is easily fixed (in spread_generic.c and cshift0.c - RESHAPE and PACK are completely failing on zero-sized arrays All others, including EOSHIFT, UNPACK, TRANSPOSE, appear to work fine. Here is a bunch of testcases, now the task is to make all these work as expected: $ cat zero_cshift.f90 real :: tempn(1), tempm(1,2) real,allocatable :: foo(:),bar(:,:),gee(:,:) tempn = 2.0 tempm = 1.0 allocate(foo(0),bar(2,0),gee(0,7)) print *, cshift(foo,dim=1,shift=1) print *, cshift(tempn(2:1),dim=1,shift=1) print *, cshift(bar,shift=(/1,-1/),dim=1) print *, cshift(bar,shift=(/1,-1/),dim=2) print *, cshift(gee,shift=(/1,-1/),dim=1) print *, cshift(gee,shift=(/1,-1/),dim=2) print *, cshift(tempm(5:4,:),shift=(/1,-1/),dim=1) print *, cshift(tempm(5:4,:),shift=(/1,-1/),dim=2) print *, cshift(tempm(:,5:4),shift=(/1,-1/),dim=1) print *, cshift(tempm(:,5:4),shift=(/1,-1/),dim=2) end $ cat zero_eoshift.f90 real :: tempn(1), tempm(1,2) real,allocatable :: foo(:),bar(:,:),gee(:,:) tempn = 2.0 tempm = 1.0 allocate(foo(0),bar(2,0),gee(0,7)) print *, eoshift(foo,dim=1,shift=1) print *, eoshift(tempn(2:1),dim=1,shift=1) print *, eoshift(bar,shift=(/1,-1/),dim=1) print *, eoshift(bar,shift=(/1,-1/),dim=2) print *, eoshift(gee,shift=(/1,-1/),dim=1) print *, eoshift(gee,shift=(/1,-1/),dim=2) print *, eoshift(tempm(5:4,:),shift=(/1,-1/),dim=1) print *, eoshift(tempm(5:4,:),shift=(/1,-1/),dim=2) print *, eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1) print *, eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2) print *, eoshift(foo,dim=1,shift=1,boundary=42.0) print *, eoshift(tempn(2:1),dim=1,shift=1,boundary=42.0) print *, eoshift(bar,shift=(/1,-1/),dim=1,boundary=42.0) print *, eoshift(bar,shift=(/1,-1/),dim=2,boundary=42.0) print *, eoshift(gee,shift=(/1,-1/),dim=1,boundary=42.0) print *, eoshift(gee,shift=(/1,-1/),dim=2,boundary=42.0) print *, eoshift(tempm(5:4,:),shift=(/1,-1/),dim=1,boundary=42.0) print *, eoshift(tempm(5:4,:),shift=(/1,-1/),dim=2,boundary=42.0) print *, eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1,boundary=42.0) print *, eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2,boundary=42.0) print *, eoshift(foo,dim=1,shift=1,boundary=(/42.0,-7.0/)) print *, eoshift(tempn(2:1),dim=1,shift=1,boundary=(/42.0,-7.0/)) print *, eoshift(bar,shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/)) print *, eoshift(bar,shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/)) print *, eoshift(gee,shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/)) print *, eoshift(gee,shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/)) print *, eoshift(tempm(5:4,:),shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/)) print *, eoshift(tempm(5:4,:),shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/)) print *, eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/)) print *, eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/)) end $ cat zero_pack.f90 integer :: tempn(1,5) integer,allocatable :: foo(:,:) tempn = 2 allocate(foo(0,1:7)) print *, pack(foo,foo/=0) print *, pack(foo,foo/=0,(/1,3,4,5,1,0,7,9/)) print *, pack(tempn(:,-4:-5),tempn(:,-4:-5)/=0) print *, pack(tempn(:,-4:-5),tempn(:,-4:-5)/=0,(/1,3,4,5,1,0,7,9/)) print *, pack(foo,.true.) print *, pack(foo,.true.,(/1,3,4,5,1,0,7,9/)) print *, pack(tempn(:,-4:-5),.true.) print *, pack(tempn(:,-4:-5),.true.,(/1,3,4,5,1,0,7,9/)) end $ cat zero_reshape.f90 character(len=1) :: tempn(1,2) character(len=1),allocatable :: foo(:,:), bar(:,:) tempn = 'a' x = 0 allocate(foo(3,0),bar(-2:-4,7:9)) print *, reshape(tempn(-7:-8,:),(/3,3/),pad=(/'a'/)) print *, reshape(tempn(-7:-8,:),(/3,3,3/),pad=(/'a'/)) print *, reshape(tempn(-7:-8,:),(/3,3,3,3,3,3,3/),pad=(/'a'/)) ! print *, reshape(tempn(:,9:8)) ! print *, reshape(foo) ! print *, reshape(bar) end $ cat zero_spread_2.f90 real,allocatable :: bar(:,:),foo(:) allocate(foo(0)) bar = spread(foo,dim=1,ncopies=1) print *, allocated(bar) end $ cat zero_spread.f90 real :: tempn(1) real,allocatable :: foo(:) tempn = 2.0 allocate(foo(0)) print *, spread(1,dim=1,ncopies=3) print *, spread(1,dim=1,ncopies=0) print *, spread(foo,dim=1,ncopies=1) print *, spread(tempn(2:1),dim=1,ncopies=1) end $ cat zero_transpose.f90 character(len=1) :: tempn(1,2) character(len=1),allocatable :: foo(:,:), bar(:,:) tempn = 'a' allocate(foo(3,0),bar(-2:-4,7:9)) print *, transpose(tempn(-7:-8,:)) print *, transpose(tempn(:,9:8)) print *, transpose(foo) print *, transpose(bar) end $ cat zero_unpack.f90 integer :: tempn(1,5), tempv(5) integer,allocatable :: foo(:,:), bar(:) tempn = 2 tempv = 5 allocate(foo(0,1:7),bar(0:-1)) print *, unpack(tempv,tempv/=0,tempv) print *, unpack(tempv(1:0),tempv/=0,tempv) print *, unpack(tempv,tempv(1:0)/=0,tempv) print *, unpack(tempv(5:4),tempv(1:0)/=0,tempv) print *, unpack(bar,foo==foo,foo) end
A patch for the library functions CSHIFT, PACK and SPREAD has been submitted: http://gcc.gnu.org/ml/gcc-patches/2006-07/msg01103.html The only one that is still not working is thus RESHAPE; it's proving difficult to fix!
Subject: Bug 27895 Author: fxcoudert Date: Thu Oct 19 21:48:50 2006 New Revision: 117890 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117890 Log: PR libfortran/27895 * intrinsics/cshift0.c: Special cases for zero-sized arrays. * intrinsics/pack_generic.c: Likewise. * intrinsics/spread_generic.c: Likewise. * gfortran.dg/zero_sized_1.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/zero_sized_1.f90 Modified: trunk/gcc/testsuite/ChangeLog trunk/libgfortran/ChangeLog trunk/libgfortran/intrinsics/cshift0.c trunk/libgfortran/intrinsics/pack_generic.c trunk/libgfortran/intrinsics/spread_generic.c
It's still not working for RESHAPE. Uncomment the test_reshape line in the newly added zero_sized_1.f90 test and see how it fails :)
Subject: Bug 27895 Author: fxcoudert Date: Fri Nov 3 11:51:09 2006 New Revision: 118455 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118455 Log: PR libfortran/27895 * intrinsics/reshape_generic.c (reshape_internal): Fix so that it works correctly for zero-sized arrays. * m4/reshape.m4: Likewise. * generated/reshape_r16.c: Regenerate. * generated/reshape_c4.c: Regenerate. * generated/reshape_i4.c: Regenerate. * generated/reshape_c16.c: Regenerate. * generated/reshape_r10.c: Regenerate. * generated/reshape_r8.c: Regenerate. * generated/reshape_c10.c: Regenerate. * generated/reshape_c8.c: Regenerate. * generated/reshape_i8.c: Regenerate. * generated/reshape_i16.c: Regenerate. * generated/reshape_r4.c: Regenerate. * gcc/testsuite/gfortran.dg/zero_sized_1.f90: Uncomment checks for RESHAPE. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/zero_sized_1.f90 trunk/libgfortran/ChangeLog trunk/libgfortran/generated/reshape_c10.c trunk/libgfortran/generated/reshape_c16.c trunk/libgfortran/generated/reshape_c4.c trunk/libgfortran/generated/reshape_c8.c trunk/libgfortran/generated/reshape_i16.c trunk/libgfortran/generated/reshape_i4.c trunk/libgfortran/generated/reshape_i8.c trunk/libgfortran/generated/reshape_r10.c trunk/libgfortran/generated/reshape_r16.c trunk/libgfortran/generated/reshape_r4.c trunk/libgfortran/generated/reshape_r8.c trunk/libgfortran/intrinsics/reshape_generic.c trunk/libgfortran/m4/reshape.m4
The patch in comments 10 and 12 will need to be backported to 4.2 and 4.1.
Subject: Bug 27895 Author: fxcoudert Date: Tue Nov 14 06:18:36 2006 New Revision: 118804 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118804 Log: PR libfortran/27895 * intrinsics/reshape_generic.c (reshape_internal): Fix so that it works correctly for zero-sized arrays. * m4/reshape.m4: Likewise. * generated/reshape_r16.c: Regenerate. * generated/reshape_c4.c: Regenerate. * generated/reshape_i4.c: Regenerate. * generated/reshape_c16.c: Regenerate. * generated/reshape_r10.c: Regenerate. * generated/reshape_r8.c: Regenerate. * generated/reshape_c10.c: Regenerate. * generated/reshape_c8.c: Regenerate. * generated/reshape_i8.c: Regenerate. * generated/reshape_i16.c: Regenerate. * generated/reshape_r4.c: Regenerate. * gcc/testsuite/gfortran.dg/zero_sized_1.f90: Uncomment checks for RESHAPE. Modified: branches/gcc-4_2-branch/gcc/testsuite/ChangeLog branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/zero_sized_1.f90 branches/gcc-4_2-branch/libgfortran/ChangeLog branches/gcc-4_2-branch/libgfortran/generated/reshape_c10.c branches/gcc-4_2-branch/libgfortran/generated/reshape_c16.c branches/gcc-4_2-branch/libgfortran/generated/reshape_c4.c branches/gcc-4_2-branch/libgfortran/generated/reshape_c8.c branches/gcc-4_2-branch/libgfortran/generated/reshape_i16.c branches/gcc-4_2-branch/libgfortran/generated/reshape_i4.c branches/gcc-4_2-branch/libgfortran/generated/reshape_i8.c branches/gcc-4_2-branch/libgfortran/generated/reshape_r10.c branches/gcc-4_2-branch/libgfortran/generated/reshape_r16.c branches/gcc-4_2-branch/libgfortran/generated/reshape_r4.c branches/gcc-4_2-branch/libgfortran/generated/reshape_r8.c branches/gcc-4_2-branch/libgfortran/intrinsics/reshape_generic.c branches/gcc-4_2-branch/libgfortran/m4/reshape.m4
Subject: Bug 27895 Author: fxcoudert Date: Tue Nov 14 06:19:04 2006 New Revision: 118805 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118805 Log: PR libfortran/27895 * intrinsics/cshift0.c: Special cases for zero-sized arrays. * intrinsics/pack_generic.c: Likewise. * intrinsics/spread_generic.c: Likewise. * intrinsics/reshape_generic.c (reshape_internal): Fix so that it works correctly for zero-sized arrays. * m4/reshape.m4: Likewise. * generated/reshape_r16.c: Regenerate. * generated/reshape_c4.c: Regenerate. * generated/reshape_i4.c: Regenerate. * generated/reshape_c16.c: Regenerate. * generated/reshape_r10.c: Regenerate. * generated/reshape_r8.c: Regenerate. * generated/reshape_c10.c: Regenerate. * generated/reshape_c8.c: Regenerate. * generated/reshape_i8.c: Regenerate. * generated/reshape_i16.c: Regenerate. * generated/reshape_r4.c: Regenerate. * gfortran.dg/zero_sized_1.f90: New test. Added: branches/gcc-4_1-branch/gcc/testsuite/gfortran.dg/zero_sized_1.f90 - copied, changed from r117890, trunk/gcc/testsuite/gfortran.dg/zero_sized_1.f90 Modified: branches/gcc-4_1-branch/gcc/testsuite/ChangeLog branches/gcc-4_1-branch/libgfortran/ChangeLog branches/gcc-4_1-branch/libgfortran/generated/reshape_c10.c branches/gcc-4_1-branch/libgfortran/generated/reshape_c16.c branches/gcc-4_1-branch/libgfortran/generated/reshape_c4.c branches/gcc-4_1-branch/libgfortran/generated/reshape_c8.c branches/gcc-4_1-branch/libgfortran/generated/reshape_i16.c branches/gcc-4_1-branch/libgfortran/generated/reshape_i4.c branches/gcc-4_1-branch/libgfortran/generated/reshape_i8.c branches/gcc-4_1-branch/libgfortran/generated/reshape_r10.c branches/gcc-4_1-branch/libgfortran/generated/reshape_r16.c branches/gcc-4_1-branch/libgfortran/intrinsics/cshift0.c branches/gcc-4_1-branch/libgfortran/intrinsics/pack_generic.c branches/gcc-4_1-branch/libgfortran/intrinsics/reshape_generic.c branches/gcc-4_1-branch/libgfortran/intrinsics/spread_generic.c branches/gcc-4_1-branch/libgfortran/m4/reshape.m4
Fixed on all active release branches.