+2009-07-08 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/40330
+ PR libfortran/40662
+ * io/io.h (st_parameter_dt): Define format_not_saved bit used to signal
+ whether the parsed format data was previously saved. Used to determine
+ if the current format data should be freed or not.
+ * io/transfer.c (st_read_done): Use the format_not_saved bit.
+ (st_write_done): Likewise.
+ * io/format.c (parse_format_list): Add boolean pointer to arg list. This
+ pointer is used to return status to the caller regarding whether it is
+ safe to cache the parsed format data. Currently, if a FMT_STRING token
+ is encounetered, it is not safe to cache. Also, added a local boolean
+ variable to hold this information as recursive calls to
+ parse_format_list are made. Remove previous save_format logic.
+ (parse_format): Do not use the format caching facility if the current
+ unit is an internal unit or if it is not safe to save parsed format
+ data.
+
2009-06-29 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/40576
* parenthesis node which contains the rest of the list. */
static fnode *
-parse_format_list (st_parameter_dt *dtp)
+parse_format_list (st_parameter_dt *dtp, bool *save_ok)
{
fnode *head, *tail;
format_token t, u, t2;
int repeat;
format_data *fmt = dtp->u.p.fmt;
- bool save_format;
+ bool saveit;
head = tail = NULL;
- save_format = !is_internal_unit (dtp);
+ saveit = *save_ok;
/* Get the next format item */
format_item:
case FMT_LPAREN:
get_fnode (fmt, &head, &tail, FMT_LPAREN);
tail->repeat = repeat;
- tail->u.child = parse_format_list (dtp);
+ tail->u.child = parse_format_list (dtp, &saveit);
if (fmt->error != NULL)
goto finished;
case FMT_LPAREN:
get_fnode (fmt, &head, &tail, FMT_LPAREN);
tail->repeat = 1;
- tail->u.child = parse_format_list (dtp);
+ tail->u.child = parse_format_list (dtp, &saveit);
if (fmt->error != NULL)
goto finished;
goto between_desc;
case FMT_STRING:
+ /* TODO: Find out why is is necessary to turn off format caching. */
+ saveit = false;
get_fnode (fmt, &head, &tail, FMT_STRING);
-
tail->u.string.p = fmt->string;
tail->u.string.length = fmt->value;
tail->repeat = 1;
case FMT_DP:
notify_std (&dtp->common, GFC_STD_F2003, "Fortran 2003: DC or DP "
"descriptor not allowed");
- save_format = true;
/* Fall through. */
case FMT_S:
case FMT_SS:
get_fnode (fmt, &head, &tail, FMT_DOLLAR);
tail->repeat = 1;
notify_std (&dtp->common, GFC_STD_GNU, "Extension: $ descriptor");
- save_format = false;
goto between_desc;
-
case FMT_T:
case FMT_TL:
case FMT_TR:
case FMT_H:
get_fnode (fmt, &head, &tail, FMT_STRING);
-
if (fmt->format_string_len < 1)
{
fmt->error = bad_hollerith;
fmt->saved_token = t;
fmt->value = 1; /* Default width */
notify_std (&dtp->common, GFC_STD_GNU, posint_required);
- save_format = false;
}
}
}
get_fnode (fmt, &head, &tail, FMT_STRING);
-
tail->u.string.p = fmt->format_string;
tail->u.string.length = repeat;
tail->repeat = 1;
goto format_item;
finished:
+
+ *save_ok = saveit;
+
return head;
}
parse_format (st_parameter_dt *dtp)
{
format_data *fmt;
+ bool format_cache_ok;
- /* Lookup format string to see if it has already been parsed. */
-
- dtp->u.p.fmt = find_parsed_format (dtp);
+ format_cache_ok = !is_internal_unit (dtp);
- if (dtp->u.p.fmt != NULL)
+ /* Lookup format string to see if it has already been parsed. */
+ if (format_cache_ok)
{
- dtp->u.p.fmt->reversion_ok = 0;
- dtp->u.p.fmt->saved_token = FMT_NONE;
- dtp->u.p.fmt->saved_format = NULL;
- reset_fnode_counters (dtp);
- return;
+ dtp->u.p.fmt = find_parsed_format (dtp);
+
+ if (dtp->u.p.fmt != NULL)
+ {
+ dtp->u.p.fmt->reversion_ok = 0;
+ dtp->u.p.fmt->saved_token = FMT_NONE;
+ dtp->u.p.fmt->saved_format = NULL;
+ reset_fnode_counters (dtp);
+ return;
+ }
}
/* Not found so proceed as follows. */
fmt->error = NULL;
fmt->value = 0;
- /* Initialize variables used during traversal of the tree */
+ /* Initialize variables used during traversal of the tree. */
fmt->reversion_ok = 0;
fmt->saved_format = NULL;
- /* Allocate the first format node as the root of the tree */
+ /* Allocate the first format node as the root of the tree. */
fmt->last = &fmt->array;
fmt->last->next = NULL;
fmt->avail++;
if (format_lex (fmt) == FMT_LPAREN)
- fmt->array.array[0].u.child = parse_format_list (dtp);
+ fmt->array.array[0].u.child = parse_format_list (dtp, &format_cache_ok);
else
fmt->error = "Missing initial left parenthesis in format";
return;
}
- /* TODO: Interim fix for PR40508. Revise this for PR40330. */
- if (!is_internal_unit(dtp))
+ if (format_cache_ok)
save_parsed_format (dtp);
+ else
+ dtp->u.p.format_not_saved = 1;
}