https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66461

--- Comment #16 from kargl at gcc dot gnu.org ---
(In reply to Jerry DeLisle from comment #10)
> This is a bandaid, but it works.
> 
> diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
> index 2490f856..726973a6 100644
> --- a/gcc/fortran/match.c
> +++ b/gcc/fortran/match.c
> @@ -1438,7 +1438,16 @@ gfc_match_if (gfc_statement *if_type)
>    if (m == MATCH_ERROR)
>      return MATCH_ERROR;
>  
> -  gfc_match (" if ( %e ) ", &expr);    /* Guaranteed to match.  */
> +  m = gfc_match (" if ( %e ) ", &expr);  /* Not always guaranteed to match.
> */
> +
> +  if (m == MATCH_ERROR)
> +    {
> +      /* Under some invalid conditions like unexpected end of file, one
> +        can get an error in the match. We bail out here and hope for
> +        the best (the best being an error reported somewhere else.  */
> +      gfc_clear_error ();
> +      return MATCH_YES;
> +    }
>  
>    m = gfc_match_pointer_assignment ();
>    if (m == MATCH_YES)
> 
> Probably need to test some variations.  I have dug around quite a bit in the
> scanner.c and other places trying to understand why this bug is only in
> fixed source. To no avail, and not sure its worth more time. I have even
> tried saving the know good locus and retoring just before the failing match
> attempt and it does not work.

I think your patch is almost correct.  A better alternative would be

Index: match.c
===================================================================
--- match.c     (revision 236243)
+++ match.c     (working copy)
@@ -1560,7 +1560,22 @@ gfc_match_if (gfc_statement *if_type)
   if (m == MATCH_ERROR)
     return MATCH_ERROR;

-  gfc_match (" if ( %e ) ", &expr);    /* Guaranteed to match.  */
+  /* This should match, but mangled fixed-form Fortran code can return
+     an allocated, but otherwise uninitialized, expr.  We check for 
+     MATCH_NO or MATCH_ERROR, then queue an error and return.  */
+  m = gfc_match (" if ( %e ) ", &expr);
+  if (gfc_current_form == FORM_FIXED && m != MATCH_YES)
+    {
+      if (expr && expr->expr_type == 0)
+       free (expr);
+      else
+        gfc_free_expr (expr);
+
+      gfc_undo_symbols ();
+      gfc_current_locus = old_loc;
+      gfc_error ("Mangled fixed-form Fortran near IF-statement at %C");
+      return MATCH_ERROR;
+    }

   m = gfc_match_pointer_assignment ();
   if (m == MATCH_YES)

Reply via email to