This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Fortran - trunk, committed] Enable bounds checking on zero length (sub)strings.
- To: gcc-patches at gcc dot gnu dot org
- Subject: [Fortran - trunk, committed] Enable bounds checking on zero length (sub)strings.
- From: Toon Moene <toon at moene dot indiv dot nluug dot nl>
- Date: Sat, 22 Sep 2001 12:43:21 +0200
- Organization: Moene Computational Physics, Maartensdijk, The Netherlands
L.S.,
I've committed the following patch by George Helffrich (attached) and
his testcase (attached) after make bootstrap, make dvi, make -k
check-g77 and make install (C and Fortran) on i686-pc-linux-gnu.
This patch enables g77 to generate code for bounds checking on zero
length character (sub)strings.
Thanks, George !
--
Toon Moene - mailto:toon@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)
*** com.c.orig Wed Sep 12 18:59:58 2001
--- com.c Sat Sep 22 10:28:16 2001
*************** ffecom_subscript_check_ (tree array, tre
*** 672,685 ****
element = ffecom_save_tree (element);
! cond = ffecom_2 (LE_EXPR, integer_type_node,
! low,
! element);
! if (high)
{
! cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
! cond,
! ffecom_2 (LE_EXPR, integer_type_node,
! element,
! high));
}
--- 672,715 ----
element = ffecom_save_tree (element);
! if (total_dims == 0)
{
! /* Special handling for substring range checks. Fortran allows the
! end subscript < begin subscript, which means that expressions like
! string(1:0) are valid (and yield a null string). In view of this,
! enforce two simpler conditions:
! 1) element<=high for end-substring;
! 2) element>=low for start-substring.
! Run-time character movement will enforce remaining conditions.
!
! More complicated checks would be better, but present structure only
! provides one index element at a time, so it is not possible to
! enforce a check of both i and j in string(i:j). If it were, the
! complete set of rules would read,
! if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
! ((low<=i<=high) && (low<=j<=high)) )
! ok ;
! else
! range error ;
! */
! if (dim)
! cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
! else
! cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
! }
! else
! {
! /* Array reference substring range checking. */
!
! cond = ffecom_2 (LE_EXPR, integer_type_node,
! low,
! element);
! if (high)
! {
! cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
! cond,
! ffecom_2 (LE_EXPR, integer_type_node,
! element,
! high));
! }
}
*** news.texi.orig Sun Jun 3 13:44:32 2001
--- news.texi Sat Sep 22 11:44:34 2001
*************** The following information was last updat
*** 157,161 ****
@ifclear USERVISONLY
@item
! [ Nothing yet ]
@end ifclear
@end itemize
--- 157,169 ----
@ifclear USERVISONLY
@item
! George Helffrich (@email{george@@geo.titech.ac.jp}) implemented a change
! in substring index checking (when specifying @code{-fbounds-check})
! that permits the use of zero length substrings of the form
! @code{string(1:0)}.
!
! @item
! Based on code developed by Pedro Vazquez (@email{vazquez@@penelope.iqm.unicamp.br}),
! the @code{libf2c} library is now able to read and write files larger than
! 2 Gbyte on 32-bit target machines, if the operating system supports this.
@end ifclear
@end itemize
C Substring range checking test program, to check behavior with respect
C to X3J3/90.4 paragraph 5.7.1.
C
C Patches relax substring checking for subscript expressions in order to
C simplify coding (elimination of length checks for strings passed as
C parameters) and to avoid contradictory behavior of subscripted substring
C expressions with respect to unsubscripted string expressions.
C
C Key part of 5.7.1 interpretation comes down to statement that in the
C substring expression,
C v ( e1 : e2 )
C 1 <= e1 <= e2 <= len to be valid, yet the expression
C v ( : )
C is equivalent to
C v(1:len(v))
C
C meaning that any statement that reads
C str = v // 'tail'
C (where v is a string passed as a parameter) would require coding as
C if (len(v) .gt. 0) then
C str = v // 'tail'
C else
C str = 'tail'
C endif
C to comply with the standard specification. Under the stricter
C interpretation, functions strcat and strlat would be incorrect as
C written for null values of str1 and/or str2.
C
C This code compiles and runs without error on
C SunOS 4.1.3 f77 (-C option)
C SUNWspro SparcCompiler 4.2 f77 (-C option)
C (and with proposed patches, gcc-2.9.2 -fbounds-check except for test 6,
C which is a genuine, deliberate error - comment out to make further
C tests)
C
C { dg-do run }
C { dg-options "-fbounds-check" }
C
C G. Helffrich/Tokyo Inst. Technology Jul 24 2001
character str*8,strres*16,strfun*16,strcat*16,strlat*16
str='Hi there'
C Test 1 - (current+patched) two char substring result
strres=strfun(str,1,2)
write(*,*) 'strres is ',strres
C Test 2 - (current+patched) null string result
strres=strfun(str,5,4)
write(*,*) 'strres is ',strres
C Test 3 - (current+patched) null string result
strres=strfun(str,8,7)
write(*,*) 'strres is ',strres
C Test 4 - (current) error; (patched) null string result
strres=strfun(str,9,8)
write(*,*) 'strres is ',strres
C Test 5 - (current) error; (patched) null string result
strres=strfun(str,1,0)
write(*,*) 'strres is ',strres
C Test 6 - (current+patched) error
C strres=strfun(str,20,20)
C write(*,*) 'strres is ',strres
C Test 7 - (current+patched) str result
strres=strcat(str,'')
write(*,*) 'strres is ',strres
C Test 8 - (current) error; (patched) str result
strres=strlat('',str)
write(*,*) 'strres is ',strres
end
character*(*) function strfun(str,i,j)
character str*(*)
strfun = str(i:j)
end
character*(*) function strcat(str1,str2)
character str1*(*), str2*(*)
strcat = str1 // str2
end
character*(*) function strlat(str1,str2)
character str1*(*), str2*(*)
strlat = str1(1:len(str1)) // str2(1:len(str2))
end