2020-8-20 José Rui Faustino de Sousa <jrfsousa@gmail.com>
authorJosé Rui Faustino de Sousa <jrfsousa@gmail.com>
Sun, 30 Aug 2020 18:10:15 +0000 (18:10 +0000)
committerJosé Rui Faustino de Sousa <jrfsousa@gmail.com>
Sun, 30 Aug 2020 18:10:15 +0000 (18:10 +0000)
gcc/fortran/ChangeLog:

PR fortran/96728
* module.c (module_peek_char): Peek ahead function.
(parse_integer): Add code for parsing signed integers.
(parse_atom): Add code to handle signed integers.
(peek_atom): Add code to handle signed integers.

gcc/testsuite/ChangeLog:

PR fortran/96728
* gfortran.dg/PR96728.f90: New test.

gcc/fortran/module.c
gcc/testsuite/gfortran.dg/PR96728.f90 [new file with mode: 0644]

index 714fbd9c299ca3bd86dd2ec0eb7573c55256e172..33e7df7d6a4a64dc55eca31e7c0c063758561c2d 100644 (file)
@@ -1234,6 +1234,13 @@ get_module_locus (module_locus *m)
   m->pos = module_pos;
 }
 
+/* Peek at the next character in the module.  */
+
+static int
+module_peek_char (void)
+{
+  return module_content[module_pos];
+}
 
 /* Get the next character in the module, updating our reckoning of
    where we are.  */
@@ -1314,7 +1321,19 @@ parse_string (void)
 static void
 parse_integer (int c)
 {
-  atom_int = c - '0';
+  int sign = 1;
+
+  atom_int = 0;
+  switch (c)
+    {
+    case ('-'):
+      sign = -1;
+    case ('+'):
+      break;
+    default:
+      atom_int = c - '0';
+      break;
+    }
 
   for (;;)
     {
@@ -1328,6 +1347,7 @@ parse_integer (int c)
       atom_int = 10 * atom_int + c - '0';
     }
 
+  atom_int *= sign; 
 }
 
 
@@ -1401,6 +1421,16 @@ parse_atom (void)
       parse_integer (c);
       return ATOM_INTEGER;
 
+    case '+':
+    case '-':
+      if (ISDIGIT (module_peek_char ()))
+       {
+         parse_integer (c);
+         return ATOM_INTEGER;
+       }
+      else
+       bad_module ("Bad name");
+
     case 'a':
     case 'b':
     case 'c':
@@ -1504,6 +1534,16 @@ peek_atom (void)
       module_unget_char ();
       return ATOM_INTEGER;
 
+    case '+':
+    case '-':
+      if (ISDIGIT (module_peek_char ()))
+       {
+         module_unget_char ();
+         return ATOM_INTEGER;
+       }
+      else
+       bad_module ("Bad name");
+
     case 'a':
     case 'b':
     case 'c':
diff --git a/gcc/testsuite/gfortran.dg/PR96728.f90 b/gcc/testsuite/gfortran.dg/PR96728.f90
new file mode 100644 (file)
index 0000000..4caa3a5
--- /dev/null
@@ -0,0 +1,49 @@
+! { dg-do run }
+!
+! Test the fix for PR96728
+!
+
+module cref_m
+
+  implicit none
+
+  private
+
+  public ::   &
+    isub_a_m
+  
+contains
+
+  subroutine isub_a_m(a, b)
+    integer, intent(in)  :: a(..)
+    integer, intent(out) :: b(size(a))
+
+    integer :: i
+    
+    b = [(i, i=1,size(b))]
+    return
+  end subroutine isub_a_m
+  
+end module cref_m
+
+program cref_p
+
+  use cref_m, only: &
+    isub_a_m
+
+  implicit none
+  
+  integer            :: i
+
+  integer, parameter :: n = 3
+  integer, parameter :: p(*) = [(i, i=1,n*n)]
+  
+  integer :: a(n,n)
+  integer :: b(n*n)
+
+  a = reshape(p, shape=[n,n])
+  call isub_a_m(a, b)
+  if (any(b/=p)) stop 1
+  stop
+
+end program cref_p