[PATCH] fortran/29403 -- Fix 'print XXX' where XXX is a char-expr.
Steve Kargl
sgk@troutmask.apl.washington.edu
Sat Oct 14 22:01:00 GMT 2006
The attached patch has been bootstrapped and regression
tested on i386-*-freebsd. The PR has a good analysis of
the problem, so see
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29403
for details. In short, "print (1,*)" is illegal and gfortran
caught this type of problem. OTOH, "print (a//(b//c)), ..."
is a legal form and gfortran did not check for this. The
patch now gets it right.
2006-10-14 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/29403
* io.c (match_io): Check for a default-char-expr for PRINT format.
2006-10-14 Steven G. Kargl <kargl@gcc.gnu.org>
gfortran.dg/print_1.f90: New test.
--
Steve
-------------- next part --------------
Index: io.c
===================================================================
--- io.c (revision 117720)
+++ io.c (working copy)
@@ -2744,7 +2744,8 @@
where = gfc_current_locus;
comma_flag = 0;
current_dt = dt = gfc_getmem (sizeof (gfc_dt));
- if (gfc_match_char ('(') == MATCH_NO)
+ m = gfc_match_char ('(');
+ if (m == MATCH_NO)
{
where = gfc_current_locus;
if (k == M_WRITE)
@@ -2796,9 +2797,25 @@
}
else
{
- /* Error for constructs like print (1,*). */
- if (k == M_PRINT)
- goto syntax;
+ /* Before issuing an error for a malformed 'print (1,*)' type of
+ error, check for a default-char-expr of the form ('(I0)'). */
+
+ if (k == M_PRINT && m == MATCH_YES)
+ {
+ /* Reset current locus to get the initial '(' in an expression. */
+ gfc_current_locus = where;
+ dt->format_expr = NULL;
+ m = match_dt_format (dt);
+
+ if (m == MATCH_ERROR)
+ goto cleanup;
+ if (m == MATCH_NO || dt->format_expr == NULL)
+ goto syntax;
+
+ comma_flag = 1;
+ dt->io_unit = default_unit (k);
+ goto get_io_list;
+ }
}
/* Match a control list */
-------------- next part --------------
! { dg-do compile }
! PR fortran/29403
program p
character(len=10) a, b, c
integer i
i = 1
print ('(I0)'), i
a = '(I0,'
b = 'I2,'
c = 'I4)'
call prn(a, b, c, i)
print (1,*), i ! { dg-error "in PRINT statement" }
end program p
subroutine prn(a, b, c, i)
integer i
character(len=*) a, b, c
print (a//(b//c)), i, i, i
print trim(a//trim(b//c)), i, i, i
end subroutine prn
More information about the Fortran
mailing list