+2005-12-30  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
+
+       PR fortran/25106
+       * parse.c (next_free): Use new prototype for gfc_match_st_label.
+       Correctly emit hard error if a label is zero.
+       * match.c (gfc_match_st_label): Never allow zero as a valid
+       label.
+       (gfc_match, gfc_match_do, gfc_match_goto): Use new prototype for
+       gfc_match_st_label.
+       * primary.c (): Use new prototype for gfc_match_st_label.
+       * io.c (): Likewise.
+       * match.h: Likewise.
+
 2005-12-02  Richard Guenther  <rguenther@suse.de>
 
        * trans.h (build1_v): Use build1, not build to build the
 
       return MATCH_YES;
     }
 
-  if (gfc_match_st_label (&label, 0) == MATCH_YES)
+  if (gfc_match_st_label (&label) == MATCH_YES)
     {
       if (dt->format_expr != NULL || dt->format_label != NULL)
        {
 
    do most of the work.  */
 
 match
-gfc_match_st_label (gfc_st_label ** label, int allow_zero)
+gfc_match_st_label (gfc_st_label ** label)
 {
   locus old_loc;
   match m;
   if (m != MATCH_YES)
     return m;
 
-  if (((i == 0) && allow_zero) || i <= 99999)
+  if (i > 0 && i <= 99999)
     {
       *label = gfc_get_st_label (i);
       return MATCH_YES;
     }
 
-  gfc_error ("Statement label at %C is out of range");
+  if (i == 0)
+    gfc_error ("Statement label at %C is zero");
+  else
+    gfc_error ("Statement label at %C is out of range");
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
 
        case 'l':
          label = va_arg (argp, gfc_st_label **);
-         n = gfc_match_st_label (label, 0);
+         n = gfc_match_st_label (label);
          if (n != MATCH_YES)
            {
              m = n;
   if (gfc_match (" do") != MATCH_YES)
     return MATCH_NO;
 
-  m = gfc_match_st_label (&label, 0);
+  m = gfc_match_st_label (&label);
   if (m == MATCH_ERROR)
     goto cleanup;
 
   gfc_match_label ();          /* This won't error */
   gfc_match (" do ");          /* This will work */
 
-  gfc_match_st_label (&label, 0);      /* Can't error out */
+  gfc_match_st_label (&label); /* Can't error out */
   gfc_match_char (',');                /* Optional comma */
 
   m = gfc_match_iterator (&iter, 0);
 
       do
        {
-         m = gfc_match_st_label (&label, 0);
+         m = gfc_match_st_label (&label);
          if (m != MATCH_YES)
            goto syntax;
 
 
   do
     {
-      m = gfc_match_st_label (&label, 0);
+      m = gfc_match_st_label (&label);
       if (m != MATCH_YES)
        goto syntax;
 
 
 match gfc_match_space (void);
 match gfc_match_eos (void);
 match gfc_match_small_literal_int (int *);
-match gfc_match_st_label (gfc_st_label **, int);
+match gfc_match_st_label (gfc_st_label **);
 match gfc_match_label (void);
 match gfc_match_small_int (int *);
 int gfc_match_strings (mstring *);
 
   if (ISDIGIT (c))
     {
       /* Found a statement label?  */
-      m = gfc_match_st_label (&gfc_statement_label, 0);
+      m = gfc_match_st_label (&gfc_statement_label);
 
       d = gfc_peek_char ();
       if (m != MATCH_YES || !gfc_is_whitespace (d))
        {
+         gfc_match_small_literal_int (&c);
+         if (c == 0)
+           gfc_error_now ("Statement label at %C is zero");
+         else
+           gfc_error_now ("Statement label at %C is out of range");
+
          do
-           {
-             /* Skip the bad statement label.  */
-             gfc_warning_now ("Ignoring bad statement label at %C");
-             c = gfc_next_char ();
-           }
-         while (ISDIGIT (c));
+           c = gfc_next_char ();
+         while (ISDIGIT(c));
        }
       else
        {
          label_locus = gfc_current_locus;
 
-         if (gfc_statement_label->value == 0)
-           {
-             gfc_warning_now ("Ignoring statement label of zero at %C");
-             gfc_free_st_label (gfc_statement_label);
-             gfc_statement_label = NULL;
-           }
-
          gfc_gobble_whitespace ();
 
          if (gfc_match_eos () == MATCH_YES)
 
 
       if (sub_flag && gfc_match_char ('*') == MATCH_YES)
        {
-         m = gfc_match_st_label (&label, 0);
+         m = gfc_match_st_label (&label);
          if (m == MATCH_NO)
            gfc_error ("Expected alternate return label at %C");
          if (m != MATCH_YES)