diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2009-04-10 10:23:25 +0300 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2009-04-10 10:23:25 +0300 |
commit | 6b6802109eeaa57a3f0c13e24dd2c4d0e05bc06c (patch) | |
tree | 8509c804d12904a38df4e5c47b9757db6a474c6d | |
parent | 8b7a6bb2faf84c3d620222c7aff68a87f9f82104 (diff) | |
download | gcc-6b6802109eeaa57a3f0c13e24dd2c4d0e05bc06c.zip gcc-6b6802109eeaa57a3f0c13e24dd2c4d0e05bc06c.tar.gz gcc-6b6802109eeaa57a3f0c13e24dd2c4d0e05bc06c.tar.bz2 |
PR libfortran/39665 libfortran/39702 libfortran/39709
2009-04-10 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/39665 libfortran/39702 libfortran/39709
* io/io.h (st_parameter_dt): Revert aligned attribute from u.p.value.
* io/list_read.c (read_complex): Read directly into user pointer.
(read_real): Likewise.
(list_formatted_read_scalar): Update read_complex and read_real calls.
(nml_read_obj): Read directly into user pointer.
From-SVN: r145875
-rw-r--r-- | libgfortran/ChangeLog | 9 | ||||
-rw-r--r-- | libgfortran/io/io.h | 5 | ||||
-rw-r--r-- | libgfortran/io/list_read.c | 39 |
3 files changed, 38 insertions, 15 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index f14cf60..ed6162b 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,12 @@ +2009-04-10 Janne Blomqvist <jb@gcc.gnu.org> + + PR libfortran/39665 libfortran/39702 libfortran/39709 + * io/io.h (st_parameter_dt): Revert aligned attribute from u.p.value. + * io/list_read.c (read_complex): Read directly into user pointer. + (read_real): Likewise. + (list_formatted_read_scalar): Update read_complex and read_real calls. + (nml_read_obj): Read directly into user pointer. + 2009-04-09 Janne Blomqvist <jb@gcc.gnu.org> PR libfortran/39665 diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 5ee0979..7e4742e 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -500,9 +500,8 @@ typedef struct st_parameter_dt int expanded_read; /* Storage area for values except for strings. Must be large enough to hold a complex value (two reals) of the - largest kind. It must also be sufficiently aligned for - assigning any type we use into it. */ - char value[32] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__))); + largest kind. */ + char value[32]; GFC_IO_INT size_used; } p; /* This pad size must be equal to the pad_size declared in diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 010474d..7cd1f60 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -1219,7 +1219,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, int length) what it is right away. */ static void -read_complex (st_parameter_dt *dtp, int kind, size_t size) +read_complex (st_parameter_dt *dtp, void * dest, int kind, size_t size) { char message[100]; char c; @@ -1243,7 +1243,7 @@ read_complex (st_parameter_dt *dtp, int kind, size_t size) } eat_spaces (dtp); - if (parse_real (dtp, dtp->u.p.value, kind)) + if (parse_real (dtp, dest, kind)) return; eol_1: @@ -1266,7 +1266,7 @@ eol_2: else unget_char (dtp, c); - if (parse_real (dtp, dtp->u.p.value + size / 2, kind)) + if (parse_real (dtp, dest + size / 2, kind)) return; eat_spaces (dtp); @@ -1300,7 +1300,7 @@ eol_2: /* Parse a real number with a possible repeat count. */ static void -read_real (st_parameter_dt *dtp, int length) +read_real (st_parameter_dt *dtp, void * dest, int length) { char c, message[100]; int seen_dp; @@ -1513,7 +1513,7 @@ read_real (st_parameter_dt *dtp, int length) unget_char (dtp, c); eat_separator (dtp); push_char (dtp, '\0'); - if (convert_real (dtp, dtp->u.p.value, dtp->u.p.saved_string, length)) + if (convert_real (dtp, dest, dtp->u.p.saved_string, length)) return; free_saved (dtp); @@ -1757,10 +1757,16 @@ list_formatted_read_scalar (st_parameter_dt *dtp, volatile bt type, void *p, read_character (dtp, kind); break; case BT_REAL: - read_real (dtp, kind); + read_real (dtp, p, kind); + /* Copy value back to temporary if needed. */ + if (dtp->u.p.repeat_count > 0) + memcpy (dtp->u.p.value, p, kind); break; case BT_COMPLEX: - read_complex (dtp, kind, size); + read_complex (dtp, p, kind, size); + /* Copy value back to temporary if needed. */ + if (dtp->u.p.repeat_count > 0) + memcpy (dtp->u.p.value, p, size); break; default: internal_error (&dtp->common, "Bad type for list read"); @@ -1776,8 +1782,12 @@ list_formatted_read_scalar (st_parameter_dt *dtp, volatile bt type, void *p, switch (dtp->u.p.saved_type) { case BT_COMPLEX: - case BT_INTEGER: case BT_REAL: + if (dtp->u.p.repeat_count > 0) + memcpy (p, dtp->u.p.value, size); + break; + + case BT_INTEGER: case BT_LOGICAL: memcpy (p, dtp->u.p.value, size); break; @@ -2379,12 +2389,17 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset, break; case GFC_DTYPE_REAL: - read_real (dtp, len); - break; + /* Need to copy data back from the real location to the temp in order + to handle nml reads into arrays. */ + read_real (dtp, pdata, len); + memcpy (dtp->u.p.value, pdata, dlen); + break; case GFC_DTYPE_COMPLEX: - read_complex (dtp, len, dlen); - break; + /* Same as for REAL, copy back to temp. */ + read_complex (dtp, pdata, len, dlen); + memcpy (dtp->u.p.value, pdata, dlen); + break; case GFC_DTYPE_DERIVED: obj_name_len = strlen (nl->var_name) + 1; |