aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2009-04-10 10:23:25 +0300
committerJanne Blomqvist <jb@gcc.gnu.org>2009-04-10 10:23:25 +0300
commit6b6802109eeaa57a3f0c13e24dd2c4d0e05bc06c (patch)
tree8509c804d12904a38df4e5c47b9757db6a474c6d
parent8b7a6bb2faf84c3d620222c7aff68a87f9f82104 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--libgfortran/io/io.h5
-rw-r--r--libgfortran/io/list_read.c39
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;