The following code program array_char implicit none integer :: i character (len=5) :: x, y character (len=5) :: z(2) x = "a " y = "cd" z = "" z = (/y(1:len(trim(y))), x(1:len(trim(x)))/) print *, "|", z(1), "| |", z(2), "|" print '(99i4)', ichar ( [ (z(1)(i:i), i=1,5) ] ) print '(99i4)', ichar ( [ (z(2)(i:i), i=1,5) ] ) end program array_char gives [ibook-dhum] f90/bug% a.out |cdI| |a` | 99 100 128 73 16 97 96 12 17 0 As reported in PR33254, comment #14, the length of the strings seems not computed inget_array_ctor_var_strlen() by: if (ref->u.ss.start->expr_type != EXPR_CONSTANT || ref->u.ss.end->expr_type != EXPR_CONSTANT) break;
According to NAG f95 the program is invalid; it prints at run time: Unequal character lengths (1 and 2) in array constructor Program terminated by fatal error In ARRAY_CHAR, line 9 of aaa.f90 I actually would expect gfortran to diagnose this with -fbounds-check.
> I actually would expect gfortran to diagnose this with -fbounds-check. Me too, but this works only if the lengths are correctly computed. The test case pass the bounds check.
changing into: z = (/y(1:len(trim(y))), x(1:len(trim(x)))//"e"/) makes this valid and shows the same issue on valid code
For the original, I am getting: |cd| |a| 99 100 0 0 0 97 0 0 0 0 and for comment #3: |cd| |ae| 99 100 0 0 0 97 101 0 0 0 Today's trunk on x86_ia64/fc5. Paul
> For the original, I am getting: ... Yes it depends of the memory content, anyway the 0 in your results should be spaces.
Dominique, > Yes it depends of the memory content, anyway the 0 in your results should be > spaces. > Ah yes. The problem is in trans-array.c(gfc_trans_array_ctor_element), where the assignment, line 975 onwards, uses memcpy and produces this code: { integer(kind=4) D.879; integer(kind=4) len.6; character(kind=1) * pstr.5; _gfortran_string_trim (&len.6, (void * *) &pstr.5, 5, &y[1]{lb: 1 sz: 1}); D.879 = len.6; if (len.6 > 0) { { void * D.878; D.878 = (void *) pstr.5; if (D.878 != 0B) { __builtin_free (D.878); } } } __builtin_memcpy (&(*(character(kind=1)[0:][1:5] *) atmp.2.data)[0][1]{lb: 1 sz: 1}, &y[1]{lb: 1 sz: 1}, MAX_EXPR <NON_LVALUE_EXPR <D.879>, 0>); } This is called in two places and the returned se->string_length could be used for bounds checking. Also, the required padding with spaces could be done too. ss->string_length has the length of the target. I am setting aside evenings of this week to a determined attack on PRs 31213, 33888 and 33998. I have solutions to most of the bugs and it now needs packaging up and submitting. If this PR still remains next week, I'll give it a try. Otherwise, I would be happy to lend a helping hand... Cheers Paul
OK then, I'll give it a try! Paul
Patch: http://gcc.gnu.org/ml/fortran/2008-01/msg00117.html
Subject: Bug 34396 Author: pault Date: Thu Jan 10 19:10:48 2008 New Revision: 131448 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131448 Log: 2008-01-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/34396 * trans-array.c (gfc_trans_array_ctor_element): Use gfc_trans_string_copy to assign strings and perform bounds checks on the string length. (get_array_ctor_strlen): Remove bounds checking. (gfc_trans_array_constructor): Initialize string length checking. * trans-array.h : Add prototype for gfc_trans_string_copy. 2008-01-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/34396 * gfortran.dg/bounds_check_12.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/bounds_check_12.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-array.c trunk/gcc/fortran/trans-array.h trunk/gcc/fortran/trans-expr.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk Paul
Subject: Bug 34396 Author: pault Date: Tue Jun 17 18:08:24 2008 New Revision: 136871 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=136871 Log: 2008-06-17 Paul Thomas <pault@gcc.gnu.org> PR fortran/34396 * resolve.c (add_dt_to_dt_list): New function. (resolve_fl_derived): Call new function for pointer components and when derived type resolved. 2008-06-17 Paul Thomas <pault@gcc.gnu.org> PR fortran/36366 * gfortran.dg/used_types_20.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/used_types_20.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog