[PATCH,gfortran] Fix for PR 17941

Steve Kargl sgk@troutmask.apl.washington.edu
Sat Jan 15 20:14:00 GMT 2005


On Sat, Jan 15, 2005 at 11:07:44AM +0000, Paul Brook wrote:
> On Friday 31 December 2004 05:57, Steve Kargl wrote:
> > The attached patch fixes PR 17941.  The attached program
> > is a test program suitable for inclusion in the gfortran
> > testsuite.
> >
> > Briefly, gfortran could not deal with spaces between an
> > uniary plus/minus sign in a complex constant.  That is,
> > "complex, parameter :: c = (-   1.0,   +  2)" would invoke
> > an error.
> 
> This is supposed to be an error. Your code is illegal in free-form source,
> and already accepted in fixed-form.
> 
> Section 4.3.1.3 "Complex type" defines a complex literal constant as a pair of 
> signed real literal constants (plus "(,)" separators).
> Section 3.2 "Low-level syntax" says that a real literal constant is a single 
> lexical token.
> Section 3.3.1 "Free source form" says that whitespace may not occur within a 
> lexical token.

Section 3.2 states (where I'm preserving the line numbers from the F2003
draft standard):

3.2       Low-level syntax
1 The low-level syntax describes the fundamental lexical tokens of a
  program unit.  Lexical tokens are
2 sequences of characters that constitute the building blocks of a
  program.  They are keywords, names,
3 literal constants other than complex literal constants, operators,
  labels, delimiters, comma, =, =>, :, ::,
4 ;, and %.

Notice the part "literal constants other than complex literal constants".
So, it appears that whitespace is permitted with a complex literal
constant because it is not a lexical token. 


Here a new patch.  Bootstrapped and regtested on i386-*-freebsd6.0.

2005-01-15  Steven G. Kargl  <kargls@comcast.net>

      PR fortran/17941
      * primary.c (match_const_complex_part): Deal with whitespace in between
      uniary sign and the number

-- 
Steve
-------------- next part --------------
Index: primary.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/primary.c,v
retrieving revision 1.15
diff -u -b -u -b -B -r1.15 primary.c
--- primary.c	3 Jan 2005 21:43:50 -0000	1.15
+++ primary.c	15 Jan 2005 20:03:54 -0000
@@ -1004,7 +1004,7 @@
 static match
 match_const_complex_part (gfc_expr ** result)
 {
-  int kind, seen_digits, seen_dp, count;
+  int kind, seen_digits, seen_dp, count, seen_sign;
   char *p, c, exp_char, *buffer;
   locus old_loc;
 
@@ -1013,12 +1013,28 @@
 
   seen_dp = 0;
   seen_digits = 0;
+  seen_sign = 0;
   count = 0;
   exp_char = ' ';
 
   c = gfc_next_char ();
-  if (c == '-' || c == '+')
+
+  /* Record the presences of uniary minus sign and gobble any whitespace
+     between the minus sign and number.  */
+  if (c == '-')
     {
+      seen_sign = -1;
+      gfc_gobble_whitespace ();
+      c = gfc_next_char ();
+      count++;
+    }
+
+  /* Record the presences of uniary plus sign and gobble any whitespace
+     between the plus sign and number.  */
+  if (c == '+')
+    { 
+      seen_sign = 1;
+      gfc_gobble_whitespace ();
       c = gfc_next_char ();
       count++;
     }
@@ -1077,14 +1093,21 @@
   gfc_gobble_whitespace ();
 
   buffer = alloca (count + 1);
-  memset (buffer, '\0', count + 1);
+  p = buffer;
+
+  /* Set the sign if present.  */
+  if (seen_sign != 0)
+    {
+      *p++ = gfc_next_char ();
+      gfc_gobble_whitespace ();
+      count--;
+    }
 
   /* Hack for mpfr_set_str().  */
-  p = buffer;
   while (count > 0)
     {
       c = gfc_next_char ();
-      if (c == 'd' || c == 'q')
+      if (c == 'd' || c == 'q')  /* FIXME:  c can never be 'q', here!  */
 	c = 'e';
       *p++ = c;
       count--;


More information about the Gcc-patches mailing list