mirror of git://gcc.gnu.org/git/gcc.git
PR 44292 Handle large record lengths
Now that the ABI supports large record lengths, there's a few places
in libgfortran where we need to use larger types. For internal units
which by definition are in-memory, it's enought to use ptrdiff_t, for
external units gfc_offset.
Regtested on x86_64-pc-linux-gnu?
libgfortran/ChangeLog:
2017-11-19 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/44292
* io/transfer.c (skip_record): Use gfc_offset to handle large
records.
(next_record_r): Likewise.
(sset): Likewise.
(next_record_w): Use gfc_offset/ptrdiff_t appropriately.
From-SVN: r254918
This commit is contained in:
parent
a7a389d6ee
commit
2563a16d3c
|
|
@ -1,3 +1,12 @@
|
||||||
|
2017-11-19 Janne Blomqvist <jb@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR fortran/44292
|
||||||
|
* io/transfer.c (skip_record): Use gfc_offset to handle large
|
||||||
|
records.
|
||||||
|
(next_record_r): Likewise.
|
||||||
|
(sset): Likewise.
|
||||||
|
(next_record_w): Use gfc_offset/ptrdiff_t appropriately.
|
||||||
|
|
||||||
2017-11-18 Janne Blomqvist <jb@gcc.gnu.org>
|
2017-11-18 Janne Blomqvist <jb@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/83036
|
PR fortran/83036
|
||||||
|
|
|
||||||
|
|
@ -3290,7 +3290,7 @@ next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
|
||||||
position. */
|
position. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
skip_record (st_parameter_dt *dtp, ssize_t bytes)
|
skip_record (st_parameter_dt *dtp, gfc_offset bytes)
|
||||||
{
|
{
|
||||||
ssize_t rlength, readb;
|
ssize_t rlength, readb;
|
||||||
#define MAX_READ 4096
|
#define MAX_READ 4096
|
||||||
|
|
@ -3367,7 +3367,6 @@ static void
|
||||||
next_record_r (st_parameter_dt *dtp, int done)
|
next_record_r (st_parameter_dt *dtp, int done)
|
||||||
{
|
{
|
||||||
gfc_offset record;
|
gfc_offset record;
|
||||||
int bytes_left;
|
|
||||||
char p;
|
char p;
|
||||||
int cc;
|
int cc;
|
||||||
|
|
||||||
|
|
@ -3419,7 +3418,7 @@ next_record_r (st_parameter_dt *dtp, int done)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bytes_left = (int) dtp->u.p.current_unit->bytes_left;
|
gfc_offset bytes_left = dtp->u.p.current_unit->bytes_left;
|
||||||
bytes_left = min_off (bytes_left,
|
bytes_left = min_off (bytes_left,
|
||||||
ssize (dtp->u.p.current_unit->s)
|
ssize (dtp->u.p.current_unit->s)
|
||||||
- stell (dtp->u.p.current_unit->s));
|
- stell (dtp->u.p.current_unit->s));
|
||||||
|
|
@ -3590,12 +3589,13 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
|
||||||
/* Utility function like memset() but operating on streams. Return
|
/* Utility function like memset() but operating on streams. Return
|
||||||
value is same as for POSIX write(). */
|
value is same as for POSIX write(). */
|
||||||
|
|
||||||
static ssize_t
|
static gfc_offset
|
||||||
sset (stream *s, int c, ssize_t nbyte)
|
sset (stream *s, int c, gfc_offset nbyte)
|
||||||
{
|
{
|
||||||
#define WRITE_CHUNK 256
|
#define WRITE_CHUNK 256
|
||||||
char p[WRITE_CHUNK];
|
char p[WRITE_CHUNK];
|
||||||
ssize_t bytes_left, trans;
|
gfc_offset bytes_left;
|
||||||
|
ssize_t trans;
|
||||||
|
|
||||||
if (nbyte < WRITE_CHUNK)
|
if (nbyte < WRITE_CHUNK)
|
||||||
memset (p, c, nbyte);
|
memset (p, c, nbyte);
|
||||||
|
|
@ -3645,11 +3645,10 @@ next_record_cc (st_parameter_dt *dtp)
|
||||||
static void
|
static void
|
||||||
next_record_w (st_parameter_dt *dtp, int done)
|
next_record_w (st_parameter_dt *dtp, int done)
|
||||||
{
|
{
|
||||||
gfc_offset m, record, max_pos;
|
gfc_offset max_pos_off;
|
||||||
int length;
|
|
||||||
|
|
||||||
/* Zero counters for X- and T-editing. */
|
/* Zero counters for X- and T-editing. */
|
||||||
max_pos = dtp->u.p.max_pos;
|
max_pos_off = dtp->u.p.max_pos;
|
||||||
dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
|
dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
|
||||||
|
|
||||||
switch (current_mode (dtp))
|
switch (current_mode (dtp))
|
||||||
|
|
@ -3674,7 +3673,7 @@ next_record_w (st_parameter_dt *dtp, int done)
|
||||||
case UNFORMATTED_DIRECT:
|
case UNFORMATTED_DIRECT:
|
||||||
if (dtp->u.p.current_unit->bytes_left > 0)
|
if (dtp->u.p.current_unit->bytes_left > 0)
|
||||||
{
|
{
|
||||||
length = (int) dtp->u.p.current_unit->bytes_left;
|
gfc_offset length = dtp->u.p.current_unit->bytes_left;
|
||||||
if (sset (dtp->u.p.current_unit->s, 0, length) != length)
|
if (sset (dtp->u.p.current_unit->s, 0, length) != length)
|
||||||
goto io_error;
|
goto io_error;
|
||||||
}
|
}
|
||||||
|
|
@ -3691,11 +3690,14 @@ next_record_w (st_parameter_dt *dtp, int done)
|
||||||
if (is_internal_unit (dtp))
|
if (is_internal_unit (dtp))
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
/* Internal unit, so must fit in memory. */
|
||||||
|
ptrdiff_t length, m, record;
|
||||||
|
ptrdiff_t max_pos = max_pos_off;
|
||||||
if (is_array_io (dtp))
|
if (is_array_io (dtp))
|
||||||
{
|
{
|
||||||
int finished;
|
int finished;
|
||||||
|
|
||||||
length = (int) dtp->u.p.current_unit->bytes_left;
|
length = dtp->u.p.current_unit->bytes_left;
|
||||||
|
|
||||||
/* If the farthest position reached is greater than current
|
/* If the farthest position reached is greater than current
|
||||||
position, adjust the position and set length to pad out
|
position, adjust the position and set length to pad out
|
||||||
|
|
@ -3705,14 +3707,14 @@ next_record_w (st_parameter_dt *dtp, int done)
|
||||||
- dtp->u.p.current_unit->bytes_left;
|
- dtp->u.p.current_unit->bytes_left;
|
||||||
if (max_pos > m)
|
if (max_pos > m)
|
||||||
{
|
{
|
||||||
length = (int) (max_pos - m);
|
length = (max_pos - m);
|
||||||
if (sseek (dtp->u.p.current_unit->s,
|
if (sseek (dtp->u.p.current_unit->s,
|
||||||
length, SEEK_CUR) < 0)
|
length, SEEK_CUR) < 0)
|
||||||
{
|
{
|
||||||
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
|
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
length = (int) (dtp->u.p.current_unit->recl - max_pos);
|
length = ((ptrdiff_t) dtp->u.p.current_unit->recl - max_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = write_block (dtp, length);
|
p = write_block (dtp, length);
|
||||||
|
|
@ -3735,7 +3737,7 @@ next_record_w (st_parameter_dt *dtp, int done)
|
||||||
dtp->u.p.current_unit->endfile = AT_ENDFILE;
|
dtp->u.p.current_unit->endfile = AT_ENDFILE;
|
||||||
|
|
||||||
/* Now seek to this record */
|
/* Now seek to this record */
|
||||||
record = record * dtp->u.p.current_unit->recl;
|
record = record * ((ptrdiff_t) dtp->u.p.current_unit->recl);
|
||||||
|
|
||||||
if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
|
if (sseek (dtp->u.p.current_unit->s, record, SEEK_SET) < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -3758,17 +3760,18 @@ next_record_w (st_parameter_dt *dtp, int done)
|
||||||
- dtp->u.p.current_unit->bytes_left;
|
- dtp->u.p.current_unit->bytes_left;
|
||||||
if (max_pos > m)
|
if (max_pos > m)
|
||||||
{
|
{
|
||||||
length = (int) (max_pos - m);
|
length = max_pos - m;
|
||||||
if (sseek (dtp->u.p.current_unit->s,
|
if (sseek (dtp->u.p.current_unit->s,
|
||||||
length, SEEK_CUR) < 0)
|
length, SEEK_CUR) < 0)
|
||||||
{
|
{
|
||||||
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
|
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
length = (int) (dtp->u.p.current_unit->recl - max_pos);
|
length = (ptrdiff_t) dtp->u.p.current_unit->recl
|
||||||
|
- max_pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
length = (int) dtp->u.p.current_unit->bytes_left;
|
length = dtp->u.p.current_unit->bytes_left;
|
||||||
}
|
}
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue