This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[libgfortran,patch] Zero-length strings messed up in library (PR33079)


Hi all,

When TRIM, MIN and MAX result is a zero-length string, the library
functions actually make it a NULL pointer instead "" (ie a pointer to
'\0'). The MIN and MAX case error is mine, because I copied the code
from TRIM when I wrote string_minmax(), while the error in
string_trim() has probably been there for a long time. This patch
fixes both. I could not see any other library routine which suffered
from this problem.

Regtested on x86_64-linux, comes with a testcase. OK for mainline?

FX



:ADDPATCH libgfortran:

2007-08-16  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>

        PR fortran/33079
        * intrinsics/string_intrinsics.c (string_trim, string_minmax):
        Fix the zero-length result case.


Index: intrinsics/string_intrinsics.c
===================================================================
--- intrinsics/string_intrinsics.c      (revision 127490)
+++ intrinsics/string_intrinsics.c      (working copy)
@@ -167,16 +167,21 @@ string_trim (GFC_INTEGER_4 * len, void *
     }
   *len = i + 1;

-  if (*len > 0)
+  if (*len == 0)
+    {
+      /* A zero-length Fortran string is "".  */
+      char * tmp = internal_malloc_size (1);
+      tmp[0] = '\0';
+      *dest = tmp;
+    }
+  else
     {
       /* Allocate space for result string.  */
       *dest = internal_malloc_size (*len);

-      /* copy string if necessary.  */
+      /* Copy string if necessary.  */
       memmove (*dest, src, *len);
     }
-  else
-    *dest = NULL;
 }


@@ -403,14 +408,18 @@ string_minmax (GFC_INTEGER_4 *rlen, void
     }
   va_end (ap);

-  if (*rlen > 0)
+  if (*rlen == 0)
+    {
+      /* A zero-length Fortran string is "".  */
+      char * tmp = internal_malloc_size (1);
+      tmp[0] = '\0';
+      *dest = tmp;
+    }
+  else
     {
       char * tmp = internal_malloc_size (*rlen);
       memcpy (tmp, res, reslen);
       memset (&tmp[reslen], ' ', *rlen - reslen);
       *dest = tmp;
     }
-  else
-    *dest = NULL;
 }
-


! { dg-do run }
  character(len=1) :: s
  character(len=0) :: s0
  s = " "
  s0 = ""
  call bar ("")
  call bar (s)
  call bar (s0)
  call bar (trim(s))
  call bar (min(s0,s0))
contains
  subroutine bar (s)
    character(len=*), optional :: s
    if (.not. present (S)) call abort
  end subroutine bar
end


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