This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/31725] overwriting of neighbouring character array
- From: "burnus at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 27 Apr 2007 17:59:17 -0000
- Subject: [Bug fortran/31725] overwriting of neighbouring character array
- References: <bug-31725-14459@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #4 from burnus at gcc dot gnu dot org 2007-04-27 18:59 -------
(Slabs oneself because of deleting important lines while deleting "only"
comments.)
Thanks for being persistent!
Reduced test case, should print twice "X,Y" but prints (once) ",Y".
The problem is that for
zsymel(3)(lenstr(zsymel(3))+1:)='X'
lenstr() is called trice instead of only once.
The assignment should be: string(1:3) = 'X '
gfortran divides this into two parts: Assigning the 'X' and assigning the two
spaces; unfortunally, it calls strlen inbetween, which gives "1" after the "X"
has been assigned. And thus:
Thus instead of string(1:1) = 'X'; string(2:3) = ' '
we do: string(1:1) = 'X'; string(1:2) = ' '
Or in the beauty of the dump:
__builtin_memmove ((char[1:_zsymel] *) &(*zsymel.0)[2][lenstr (&(*zsymel.0)[2],
_zsymel) + 1]{lb: 1 sz: 1}, "X", 1);
__builtin_memset ((char[1:_zsymel] *) &(*zsymel.0)[2][lenstr (&(*zsymel.0)[2],
_zsymel) + 1]{lb: 1 sz: 1} + 1B, 32, (int8) D
In addition it is called before in order to test whether an assignment should
be done at all:
D.1374 = MAX_EXPR <_zsymel - lenstr (&(*zsymel.0)[2], _zsymel), 0>;
As lenstr could have side effects and because of speed, it makes sense to call
it only once and not twice or - as here - trice.
Example program:
program char3
implicit none
character(3), dimension(3) :: zsymel,zsymelr
common /xx/ zsymel, zsymelr
integer :: znsymelr
zsymel = (/ 'X', 'Y', ' ' /)
zsymelr= (/ 'X', 'Y', ' ' /)
znsymelr=2
call check_zsymel(zsymel,zsymelr,znsymelr)
contains
subroutine check_zsymel(zsymel,zsymelr,znsymelr)
implicit none
integer znsymelr, isym
character(*) zsymel(*),zsymelr(*)
zsymel(3)(lenstr(zsymel(3))+1:)='X'
write (*,10) (trim(zsymelr(isym)),isym=1,znsymelr)
10 format(3(a,:,','))
end subroutine check_zsymel
function lenstr(s)
character(len=*),intent(in) :: s
integer :: lenstr
print *, 's: ',len_trim(s)
lenstr = len_trim(s)
end function lenstr
end program
--
burnus at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever Confirmed|0 |1
GCC build triplet|i386-apple-darwin8.9.1 |
GCC host triplet|i386-apple-darwin8.9.1 |
GCC target triplet|i386-apple-darwin8.9.1 |
Keywords| |wrong-code
Last reconfirmed|0000-00-00 00:00:00 |2007-04-27 18:59:17
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31725