[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