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]
Other format: [Raw text]

[patch, libgfortran] PR 31915 - fix reading/writing of real(10) variables with convert="SWAP"


:ADDPATCH fortran:

The following was failing:

  real(10) :: a,b
  open(10,convert="swap",form="unformatted")
  write(10) a
  backspace 10
  read (10) b
  if (a /= b) call abort


real(10) == long double on my machine; sizeof(long double) == 16 and
kind == 10. Therefore, we wrote/read to few bytes from the unformatted file.

Test case:  gfortran.dg/unf_io_convert_3.f90. Ask Dominique or Jerry why
this test is not used.

Build and regression tested on x86_64-unknown-linux-gnu.

Ok for the trunk? Ok for GCC 4.2.1?

Tobias


PS: This does not fix all problems. If I run valgrind on the produced
a.out, I still get the following output.

==28541== Syscall param write(buf) points to uninitialised byte(s)
==28541==    at 0x5601550: write (in /lib64/libc-2.5.so)
==28541==    by 0x4EBF610: do_write (unix.c:336)
==28541==    by 0x4EBF6B1: fd_flush (unix.c:386)
==28541==    by 0x4EB3512: _gfortran_st_backspace (file_pos.c:230)
==28541==    by 0x400AF1: MAIN__ (in /dev/shm/a.out)
==28541==    by 0x400D8B: main (fmain.c:22)
==28541==  Address 0x40517E1 is 153 bytes inside a block of size 8,344
alloc'd
==28541==    at 0x4C22D06: malloc (in
/usr/lib64/valgrind/amd64-linux/vgpreload_memcheck.so)
==28541==    by 0x4E3EFB8: _gfortrani_get_mem (memory.c:53)
==28541==    by 0x4EC0079: fd_to_stream (unix.c:1043)
==28541==    by 0x4EB9574: _gfortrani_new_unit (open.c:376)
==28541==    by 0x4EB9BDA: _gfortran_st_open (open.c:561)
==28541==    by 0x400A66: MAIN__ (in /dev/shm/a.out)
==28541==    by 0x400D8B: main (fmain.c:22)
2007-05-14  Tobias Burnus  <burnus@net-b.de>

	PR libfortran/31915
	* io/transfer.c (unformatted_read): Use proper size for real(10).
	  (unformatted_write): Ditto.

Index: libgfortran/io/transfer.c
===================================================================
--- libgfortran/io/transfer.c	(Revision 124718)
+++ libgfortran/io/transfer.c	(Arbeitskopie)
@@ -726,7 +726,11 @@ unformatted_read (st_parameter_dt *dtp, 
 	 of the padding.  If we hit a short record, then sz is
 	 adjusted accordingly, making later reads no-ops.  */
       
-      sz = kind;
+      if (type == BT_REAL || BT_COMPLEX)
+	sz = size_from_real_kind (kind);
+      else
+	sz = kind;
+
       for (i=0; i<nelems; i++)
 	{
  	  read_block_direct (dtp, buffer, &sz);
@@ -771,7 +775,11 @@ unformatted_write (st_parameter_dt *dtp,
 	 read kind bytes.  We don't care about the contents
 	 of the padding.  */
 
-      sz = kind;
+      if (type == BT_REAL || BT_COMPLEX)
+	sz = size_from_real_kind (kind);
+      else
+	sz = kind;
+
       for (i=0; i<nelems; i++)
 	{
 	  reverse_memcpy(buffer, p, size);

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