This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[Fortran - trunk, committed] Enable bounds checking on zero length (sub)strings.


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]