mirror of git://gcc.gnu.org/git/gcc.git
backport: re PR fortran/65089 (FAIL: gfortran.dg/io_real_boz(2|_[45]).f90 when tested with -fsanitize=address)
2015-11-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
Backport from trunk
PR libgfortran/65089
* io/format.h (free_format): New function to free memory
allocated for building format error messages.
* io/format.c (format_error): Add checks before freeing memory
to avoid potential segfaults and free formatting data when
needed on error conditions. Always allocate and NULL terminate
the string.
* io/transfer.c (st_read_done, st_write_done): Use new
free_format function to clean up memory allocations when done.
From-SVN: r229935
This commit is contained in:
parent
13eca6e571
commit
c6e74afc2a
|
|
@ -1,3 +1,16 @@
|
||||||
|
2015-11-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||||
|
|
||||||
|
Backport from trunk
|
||||||
|
PR libgfortran/65089
|
||||||
|
* io/format.h (free_format): New function to free memory
|
||||||
|
allocated for building format error messages.
|
||||||
|
* io/format.c (format_error): Add checks before freeing memory
|
||||||
|
to avoid potential segfaults and free formatting data when
|
||||||
|
needed on error conditions. Always allocate and NULL terminate
|
||||||
|
the string.
|
||||||
|
* io/transfer.c (st_read_done, st_write_done): Use new
|
||||||
|
free_format function to clean up memory allocations when done.
|
||||||
|
|
||||||
2015-09-02 Janne Blomqvist <jb@gcc.gnu.org>
|
2015-09-02 Janne Blomqvist <jb@gcc.gnu.org>
|
||||||
|
|
||||||
PR libfortran/67414
|
PR libfortran/67414
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,18 @@ get_fnode (format_data *fmt, fnode **head, fnode **tail, format_token t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* free_format()-- Free allocated format string. */
|
||||||
|
void
|
||||||
|
free_format (st_parameter_dt *dtp)
|
||||||
|
{
|
||||||
|
if ((dtp->common.flags & IOPARM_DT_HAS_FORMAT) && dtp->format)
|
||||||
|
{
|
||||||
|
free (dtp->format);
|
||||||
|
dtp->format = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* free_format_data()-- Free all allocated format data. */
|
/* free_format_data()-- Free all allocated format data. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1145,7 +1157,8 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
|
||||||
|
|
||||||
p = strchr (buffer, '\0');
|
p = strchr (buffer, '\0');
|
||||||
|
|
||||||
memcpy (p, dtp->format, width);
|
if (dtp->format)
|
||||||
|
memcpy (p, dtp->format, width);
|
||||||
|
|
||||||
p += width;
|
p += width;
|
||||||
*p++ = '\n';
|
*p++ = '\n';
|
||||||
|
|
@ -1158,6 +1171,26 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
|
||||||
*p++ = '^';
|
*p++ = '^';
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
|
/* Cleanup any left over memory allocations before calling generate
|
||||||
|
error. */
|
||||||
|
if (is_internal_unit (dtp))
|
||||||
|
{
|
||||||
|
if (dtp->format != NULL)
|
||||||
|
{
|
||||||
|
free (dtp->format);
|
||||||
|
dtp->format = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave these alone if IOSTAT was given because execution will
|
||||||
|
return from generate error in those cases. */
|
||||||
|
if (!(dtp->common.flags & IOPARM_HAS_IOSTAT))
|
||||||
|
{
|
||||||
|
free (dtp->u.p.fmt);
|
||||||
|
free_format_hash_table (dtp->u.p.current_unit);
|
||||||
|
free_internal_unit (dtp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
|
generate_error (&dtp->common, LIBERROR_FORMAT, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1218,13 +1251,8 @@ parse_format (st_parameter_dt *dtp)
|
||||||
|
|
||||||
/* Not found so proceed as follows. */
|
/* Not found so proceed as follows. */
|
||||||
|
|
||||||
if (format_cache_ok)
|
char *fmt_string = fc_strdup_notrim (dtp->format, dtp->format_len);
|
||||||
{
|
dtp->format = fmt_string;
|
||||||
char *fmt_string = xmalloc (dtp->format_len + 1);
|
|
||||||
memcpy (fmt_string, dtp->format, dtp->format_len);
|
|
||||||
dtp->format = fmt_string;
|
|
||||||
dtp->format[dtp->format_len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));
|
dtp->u.p.fmt = fmt = xmalloc (sizeof (format_data));
|
||||||
fmt->format_string = dtp->format;
|
fmt->format_string = dtp->format;
|
||||||
|
|
@ -1256,19 +1284,13 @@ parse_format (st_parameter_dt *dtp)
|
||||||
else
|
else
|
||||||
fmt->error = "Missing initial left parenthesis in format";
|
fmt->error = "Missing initial left parenthesis in format";
|
||||||
|
|
||||||
if (fmt->error)
|
|
||||||
{
|
|
||||||
format_error (dtp, NULL, fmt->error);
|
|
||||||
if (format_cache_ok)
|
|
||||||
free (dtp->format);
|
|
||||||
free_format_hash_table (dtp->u.p.current_unit);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format_cache_ok)
|
if (format_cache_ok)
|
||||||
save_parsed_format (dtp);
|
save_parsed_format (dtp);
|
||||||
else
|
else
|
||||||
dtp->u.p.format_not_saved = 1;
|
dtp->u.p.format_not_saved = 1;
|
||||||
|
|
||||||
|
if (fmt->error)
|
||||||
|
format_error (dtp, NULL, fmt->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,9 @@ internal_proto(format_error);
|
||||||
extern void free_format_data (struct format_data *);
|
extern void free_format_data (struct format_data *);
|
||||||
internal_proto(free_format_data);
|
internal_proto(free_format_data);
|
||||||
|
|
||||||
|
extern void free_format (st_parameter_dt *);
|
||||||
|
internal_proto(free_format);
|
||||||
|
|
||||||
extern void free_format_hash_table (gfc_unit *);
|
extern void free_format_hash_table (gfc_unit *);
|
||||||
internal_proto(free_format_hash_table);
|
internal_proto(free_format_hash_table);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3711,9 +3711,15 @@ void
|
||||||
st_read_done (st_parameter_dt *dtp)
|
st_read_done (st_parameter_dt *dtp)
|
||||||
{
|
{
|
||||||
finalize_transfer (dtp);
|
finalize_transfer (dtp);
|
||||||
|
|
||||||
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
|
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
|
||||||
free_format_data (dtp->u.p.fmt);
|
{
|
||||||
|
free_format_data (dtp->u.p.fmt);
|
||||||
|
free_format (dtp);
|
||||||
|
}
|
||||||
|
|
||||||
free_ionml (dtp);
|
free_ionml (dtp);
|
||||||
|
|
||||||
if (dtp->u.p.current_unit != NULL)
|
if (dtp->u.p.current_unit != NULL)
|
||||||
unlock_unit (dtp->u.p.current_unit);
|
unlock_unit (dtp->u.p.current_unit);
|
||||||
|
|
||||||
|
|
@ -3764,8 +3770,13 @@ st_write_done (st_parameter_dt *dtp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
|
if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
|
||||||
free_format_data (dtp->u.p.fmt);
|
{
|
||||||
|
free_format_data (dtp->u.p.fmt);
|
||||||
|
free_format (dtp);
|
||||||
|
}
|
||||||
|
|
||||||
free_ionml (dtp);
|
free_ionml (dtp);
|
||||||
|
|
||||||
if (dtp->u.p.current_unit != NULL)
|
if (dtp->u.p.current_unit != NULL)
|
||||||
unlock_unit (dtp->u.p.current_unit);
|
unlock_unit (dtp->u.p.current_unit);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue