re PR fortran/35832 (Better error message for wrong arguments to I/O statements)
authorTobias Schlüter <tobi@gcc.gnu.org>
Sun, 6 Apr 2008 18:58:34 +0000 (20:58 +0200)
committerTobias Schlüter <tobi@gcc.gnu.org>
Sun, 6 Apr 2008 18:58:34 +0000 (20:58 +0200)
2008-04-06  Tobias Schlter  <tobi@gcc.gnu.org>

PR fortran/35832
fortran/
* io.c (io_tag): Add field 'value'.  Split 'spec' field in
existing io_tags.
(match_etag, match_vtag, match_ltag): Split parsing in two steps
to give better error messages.
testsuite/
* gfortran.dg/io_constraints_2.f90: Adapt to new error message.

From-SVN: r133964

gcc/fortran/ChangeLog
gcc/fortran/io.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/io_constraints_2.f90

index 49c8a0c32d37d738177b1afff8d565f71b57ded9..160d602dfd1938eec9ac6d0c3a4441e682829145 100644 (file)
@@ -1,3 +1,11 @@
+2008-04-06  Tobias Schlüter  <tobi@gcc.gnu.org>
+
+       PR fortran/35832
+       * io.c (io_tag): Add field 'value'.  Split 'spec' field in
+       existing io_tags.
+       (match_etag, match_vtag, match_ltag): Split parsing in two steps
+       to give better error messages.
+
 2008-04-06  Tobias Burnus  <burnus@net-b.de>
 
        * io.c (check_io_constraints): Add constrains. ID= requires
index 034039f87e094beb7d424d9f4897fe59c8cd874e..5ea051c87f94870954ffd69213e8b61e16406a65 100644 (file)
@@ -32,63 +32,63 @@ format_asterisk = {0, NULL, NULL, -1, ST_LABEL_FORMAT, ST_LABEL_FORMAT, NULL,
 
 typedef struct
 {
-  const char *name, *spec;
+  const char *name, *spec, *value;
   bt type;
 }
 io_tag;
 
 static const io_tag
-       tag_file        = { "FILE", " file = %e", BT_CHARACTER },
-       tag_status      = { "STATUS", " status = %e", BT_CHARACTER},
-       tag_e_access    = {"ACCESS", " access = %e", BT_CHARACTER},
-       tag_e_form      = {"FORM", " form = %e", BT_CHARACTER},
-       tag_e_recl      = {"RECL", " recl = %e", BT_INTEGER},
-       tag_e_blank     = {"BLANK", " blank = %e", BT_CHARACTER},
-       tag_e_position  = {"POSITION", " position = %e", BT_CHARACTER},
-       tag_e_action    = {"ACTION", " action = %e", BT_CHARACTER},
-       tag_e_delim     = {"DELIM", " delim = %e", BT_CHARACTER},
-       tag_e_pad       = {"PAD", " pad = %e", BT_CHARACTER},
-       tag_e_decimal   = {"DECIMAL", " decimal = %e", BT_CHARACTER},
-       tag_e_encoding  = {"ENCODING", " encoding = %e", BT_CHARACTER},
-       tag_e_round     = {"ROUND", " round = %e", BT_CHARACTER},
-       tag_e_sign      = {"SIGN", " sign = %e", BT_CHARACTER},
-       tag_unit        = {"UNIT", " unit = %e", BT_INTEGER},
-       tag_advance     = {"ADVANCE", " advance = %e", BT_CHARACTER},
-       tag_rec         = {"REC", " rec = %e", BT_INTEGER},
-       tag_spos        = {"POSITION", " pos = %e", BT_INTEGER},
-       tag_format      = {"FORMAT", NULL, BT_CHARACTER},
-       tag_iomsg       = {"IOMSG", " iomsg = %e", BT_CHARACTER},
-       tag_iostat      = {"IOSTAT", " iostat = %v", BT_INTEGER},
-       tag_size        = {"SIZE", " size = %v", BT_INTEGER},
-       tag_exist       = {"EXIST", " exist = %v", BT_LOGICAL},
-       tag_opened      = {"OPENED", " opened = %v", BT_LOGICAL},
-       tag_named       = {"NAMED", " named = %v", BT_LOGICAL},
-       tag_name        = {"NAME", " name = %v", BT_CHARACTER},
-       tag_number      = {"NUMBER", " number = %v", BT_INTEGER},
-       tag_s_access    = {"ACCESS", " access = %v", BT_CHARACTER},
-       tag_sequential  = {"SEQUENTIAL", " sequential = %v", BT_CHARACTER},
-       tag_direct      = {"DIRECT", " direct = %v", BT_CHARACTER},
-       tag_s_form      = {"FORM", " form = %v", BT_CHARACTER},
-       tag_formatted   = {"FORMATTED", " formatted = %v", BT_CHARACTER},
-       tag_unformatted = {"UNFORMATTED", " unformatted = %v", BT_CHARACTER},
-       tag_s_recl      = {"RECL", " recl = %v", BT_INTEGER},
-       tag_nextrec     = {"NEXTREC", " nextrec = %v", BT_INTEGER},
-       tag_s_blank     = {"BLANK", " blank = %v", BT_CHARACTER},
-       tag_s_position  = {"POSITION", " position = %v", BT_CHARACTER},
-       tag_s_action    = {"ACTION", " action = %v", BT_CHARACTER},
-       tag_read        = {"READ", " read = %v", BT_CHARACTER},
-       tag_write       = {"WRITE", " write = %v", BT_CHARACTER},
-       tag_readwrite   = {"READWRITE", " readwrite = %v", BT_CHARACTER},
-       tag_s_delim     = {"DELIM", " delim = %v", BT_CHARACTER},
-       tag_s_pad       = {"PAD", " pad = %v", BT_CHARACTER},
-       tag_iolength    = {"IOLENGTH", " iolength = %v", BT_INTEGER},
-       tag_convert     = {"CONVERT", " convert = %e", BT_CHARACTER},
-       tag_strm_out    = {"POS", " pos = %v", BT_INTEGER},
-       tag_err         = {"ERR", " err = %l", BT_UNKNOWN},
-       tag_end         = {"END", " end = %l", BT_UNKNOWN},
-       tag_eor         = {"EOR", " eor = %l", BT_UNKNOWN},
-       tag_async       = {"ASYNCHRONOUS", " asynchronous = %e", BT_CHARACTER},
-       tag_id          = {"ID", " id = %v", BT_INTEGER};
+       tag_file        = { "FILE", " file =", " %e", BT_CHARACTER },
+       tag_status      = { "STATUS", " status =", " %e", BT_CHARACTER},
+       tag_e_access    = {"ACCESS", " access =", " %e", BT_CHARACTER},
+       tag_e_form      = {"FORM", " form =", " %e", BT_CHARACTER},
+       tag_e_recl      = {"RECL", " recl =", " %e", BT_INTEGER},
+       tag_e_blank     = {"BLANK", " blank =", " %e", BT_CHARACTER},
+       tag_e_position  = {"POSITION", " position =", " %e", BT_CHARACTER},
+       tag_e_action    = {"ACTION", " action =", " %e", BT_CHARACTER},
+       tag_e_delim     = {"DELIM", " delim =", " %e", BT_CHARACTER},
+       tag_e_pad       = {"PAD", " pad =", " %e", BT_CHARACTER},
+       tag_e_decimal   = {"DECIMAL", " decimal =", " %e", BT_CHARACTER},
+       tag_e_encoding  = {"ENCODING", " encoding =", " %e", BT_CHARACTER},
+       tag_e_round     = {"ROUND", " round =", " %e", BT_CHARACTER},
+       tag_e_sign      = {"SIGN", " sign =", " %e", BT_CHARACTER},
+       tag_unit        = {"UNIT", " unit =", " %e", BT_INTEGER},
+       tag_advance     = {"ADVANCE", " advance =", " %e", BT_CHARACTER},
+       tag_rec         = {"REC", " rec =", " %e", BT_INTEGER},
+       tag_spos        = {"POSITION", " pos =", " %e", BT_INTEGER},
+       tag_format      = {"FORMAT", NULL, NULL, BT_CHARACTER},
+       tag_iomsg       = {"IOMSG", " iomsg =", " %e", BT_CHARACTER},
+       tag_iostat      = {"IOSTAT", " iostat =", " %v", BT_INTEGER},
+       tag_size        = {"SIZE", " size =", " %v", BT_INTEGER},
+       tag_exist       = {"EXIST", " exist =", " %v", BT_LOGICAL},
+       tag_opened      = {"OPENED", " opened =", " %v", BT_LOGICAL},
+       tag_named       = {"NAMED", " named =", " %v", BT_LOGICAL},
+       tag_name        = {"NAME", " name =", " %v", BT_CHARACTER},
+       tag_number      = {"NUMBER", " number =", " %v", BT_INTEGER},
+       tag_s_access    = {"ACCESS", " access =", " %v", BT_CHARACTER},
+       tag_sequential  = {"SEQUENTIAL", " sequential =", " %v", BT_CHARACTER},
+       tag_direct      = {"DIRECT", " direct =", " %v", BT_CHARACTER},
+       tag_s_form      = {"FORM", " form =", " %v", BT_CHARACTER},
+       tag_formatted   = {"FORMATTED", " formatted =", " %v", BT_CHARACTER},
+       tag_unformatted = {"UNFORMATTED", " unformatted =", " %v", BT_CHARACTER},
+       tag_s_recl      = {"RECL", " recl =", " %v", BT_INTEGER},
+       tag_nextrec     = {"NEXTREC", " nextrec =", " %v", BT_INTEGER},
+       tag_s_blank     = {"BLANK", " blank =", " %v", BT_CHARACTER},
+       tag_s_position  = {"POSITION", " position =", " %v", BT_CHARACTER},
+       tag_s_action    = {"ACTION", " action =", " %v", BT_CHARACTER},
+       tag_read        = {"READ", " read =", " %v", BT_CHARACTER},
+       tag_write       = {"WRITE", " write =", " %v", BT_CHARACTER},
+       tag_readwrite   = {"READWRITE", " readwrite =", " %v", BT_CHARACTER},
+       tag_s_delim     = {"DELIM", " delim =", " %v", BT_CHARACTER},
+       tag_s_pad       = {"PAD", " pad =", " %v", BT_CHARACTER},
+       tag_iolength    = {"IOLENGTH", " iolength =", " %v", BT_INTEGER},
+       tag_convert     = {"CONVERT", " convert =", " %e", BT_CHARACTER},
+       tag_strm_out    = {"POS", " pos =", " %v", BT_INTEGER},
+       tag_err         = {"ERR", " err =", " %l", BT_UNKNOWN},
+       tag_end         = {"END", " end =", " %l", BT_UNKNOWN},
+       tag_eor         = {"EOR", " eor =", " %l", BT_UNKNOWN},
+       tag_async       = {"ASYNCHRONOUS", " asynchronous =", " %e", BT_CHARACTER},
+       tag_id          = {"ID", " id =", " %v", BT_INTEGER};
 
 static gfc_dt *current_dt;
 
@@ -1031,10 +1031,17 @@ match_etag (const io_tag *tag, gfc_expr **v)
   gfc_expr *result;
   match m;
 
-  m = gfc_match (tag->spec, &result);
+  m = gfc_match (tag->spec);
   if (m != MATCH_YES)
     return m;
 
+  m = gfc_match (tag->value, &result);
+  if (m != MATCH_YES)
+    {
+      gfc_error ("Invalid value for %s specification at %C", tag->name);
+      return MATCH_ERROR;
+    }
+
   if (*v != NULL)
     {
       gfc_error ("Duplicate %s specification at %C", tag->name);
@@ -1055,10 +1062,17 @@ match_vtag (const io_tag *tag, gfc_expr **v)
   gfc_expr *result;
   match m;
 
-  m = gfc_match (tag->spec, &result);
+  m = gfc_match (tag->spec);
   if (m != MATCH_YES)
     return m;
 
+  m = gfc_match (tag->value, &result);
+  if (m != MATCH_YES)
+    {
+      gfc_error ("Invalid value for %s specification at %C", tag->name);
+      return MATCH_ERROR;
+    }
+
   if (*v != NULL)
     {
       gfc_error ("Duplicate %s specification at %C", tag->name);
@@ -1109,15 +1123,24 @@ match_ltag (const io_tag *tag, gfc_st_label ** label)
   gfc_st_label *old;
 
   old = *label;
-  m = gfc_match (tag->spec, label);
-  if (m == MATCH_YES && old != 0)
+  m = gfc_match (tag->spec);
+  if (m != MATCH_YES)
+    return m;
+
+  m = gfc_match (tag->value, label);
+  if (m != MATCH_YES)
+    {
+      gfc_error ("Invalid value for %s specification at %C", tag->name);
+      return MATCH_ERROR;
+    }
+
+  if (old)
     {
       gfc_error ("Duplicate %s label specification at %C", tag->name);
       return MATCH_ERROR;
     }
 
-  if (m == MATCH_YES 
-      && gfc_reference_st_label (*label, ST_LABEL_TARGET) == FAILURE)
+  if (gfc_reference_st_label (*label, ST_LABEL_TARGET) == FAILURE)
     return MATCH_ERROR;
 
   return m;
index 528bafabc02d8c8d6188d666efe8bfa279f4e790..9f9caa65ce5e877491465430ac26e06e0e62ab1e 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-06  Tobias Schlüter  <tobi@gcc.gnu.org>
+
+       PR fortran/35832
+       * gfortran.dg/io_constraints_2.f90: Adapt to new error message.
+
 2008-04-06  Tobias Burnus  <burnus@net-b.de>
 
        * gfortran.dg/f2003_io_1.f03: Make standard conform.
index fa6cbdbca6ba7138d1145bccb02cf1d925ddaf82..8bf48d72ff20c4927b31a2302e1d19877d1256aa 100644 (file)
@@ -66,7 +66,7 @@ end module global
 
  READ(1, fmt='(i6)', advance='NO', size = buffer) a ! { dg-error "INTEGER" }
 !Was correctly picked up before patch. -correct syntax error
- READ(1, fmt='(i6)', advance='YES', size = 10) a    ! { dg-error "Syntax error" }
+ READ(1, fmt='(i6)', advance='YES', size = 10) a    ! { dg-error "Invalid value for SIZE specification" }
 
  READ(1, fmt='(i6)', advance='MAYBE')               !  { dg-error "YES or NO" }