gfortran.h (MAX_ERROR_MESSAGE): Remove.
authorJakub Jelinek <jakub@redhat.com>
Thu, 14 Jul 2005 10:12:17 +0000 (12:12 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 14 Jul 2005 10:12:17 +0000 (12:12 +0200)
* gfortran.h (MAX_ERROR_MESSAGE): Remove.
(gfc_error_buf): Add allocated and index fields.  Change message
field from array to a pointer.
* error.c (use_warning_buffer, error_ptr, warning_ptr): Remove.
(cur_error_buffer): New variable.
(error_char): Use cur_error_buffer->{message,index} instead of
{warning,error}_{buffer.message,ptr}.  Reallocate message buffer
if too small.
(gfc_warning, gfc_notify_std, gfc_error, gfc_error_now): Setup
cur_error_buffer and its index rather than {warning,error}_ptr
and use_warning_buffer.
(gfc_warning_check, gfc_error_check): Don't print anything if
message is NULL.
(gfc_push_error): Allocate saved message with xstrdup.
(gfc_pop_error): Free saved message with gfc_free.
(gfc_free_error): New function.
* primary.c (match_complex_constant): Call gfc_free_error if
gfc_pop_error will not be called.
* match.c (gfc_match_st_function): Likewise.

* gfortran.dg/g77/cpp6.f: New test.

From-SVN: r102015

gcc/fortran/ChangeLog
gcc/fortran/error.c
gcc/fortran/gfortran.h
gcc/fortran/match.c
gcc/fortran/primary.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/g77/cpp6.f [new file with mode: 0644]

index 5f17e5edc6b7d6c143c1bf44260b7593b203f036..8fd316abb0f22dd87a010921f27dea5a8226b632 100644 (file)
@@ -1,5 +1,25 @@
 2005-07-14  Jakub Jelinek  <jakub@redhat.com>
 
+       * gfortran.h (MAX_ERROR_MESSAGE): Remove.
+       (gfc_error_buf): Add allocated and index fields.  Change message
+       field from array to a pointer.
+       * error.c (use_warning_buffer, error_ptr, warning_ptr): Remove.
+       (cur_error_buffer): New variable.
+       (error_char): Use cur_error_buffer->{message,index} instead of
+       {warning,error}_{buffer.message,ptr}.  Reallocate message buffer
+       if too small.
+       (gfc_warning, gfc_notify_std, gfc_error, gfc_error_now): Setup
+       cur_error_buffer and its index rather than {warning,error}_ptr
+       and use_warning_buffer.
+       (gfc_warning_check, gfc_error_check): Don't print anything if
+       message is NULL.
+       (gfc_push_error): Allocate saved message with xstrdup.
+       (gfc_pop_error): Free saved message with gfc_free.
+       (gfc_free_error): New function.
+       * primary.c (match_complex_constant): Call gfc_free_error if
+       gfc_pop_error will not be called.
+       * match.c (gfc_match_st_function): Likewise.
+
        PR fortran/22417
        * scanner.c (preprocessor_line): Don't treat flag 3 as the start of a new
        file.  Fix file left but not entered warning.
index fe7decc5dfbf75250ab04cd92abc4603ccede885..009419a0979614c48e73c930437ada7eaf88716e 100644 (file)
@@ -33,12 +33,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 
 int gfc_suppress_error = 0;
 
-static int terminal_width, buffer_flag, errors,
-  use_warning_buffer, warnings;
+static int terminal_width, buffer_flag, errors, warnings;
 
-static char *error_ptr, *warning_ptr;
-
-static gfc_error_buf error_buffer, warning_buffer;
+static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer;
 
 
 /* Per-file error initialization.  */
@@ -70,18 +67,16 @@ error_char (char c)
 {
   if (buffer_flag)
     {
-      if (use_warning_buffer)
+      if (cur_error_buffer->index >= cur_error_buffer->allocated)
        {
-         *warning_ptr++ = c;
-         if (warning_ptr - warning_buffer.message >= MAX_ERROR_MESSAGE)
-           gfc_internal_error ("error_char(): Warning buffer overflow");
-       }
-      else
-       {
-         *error_ptr++ = c;
-         if (error_ptr - error_buffer.message >= MAX_ERROR_MESSAGE)
-           gfc_internal_error ("error_char(): Error buffer overflow");
+         cur_error_buffer->allocated =
+           cur_error_buffer->allocated
+           ? cur_error_buffer->allocated * 2 : 1000;
+         cur_error_buffer->message
+           = xrealloc (cur_error_buffer->message,
+                       cur_error_buffer->allocated);
        }
+      cur_error_buffer->message[cur_error_buffer->index++] = c;
     }
   else
     {
@@ -89,11 +84,16 @@ error_char (char c)
        {
          /* We build up complete lines before handing things
             over to the library in order to speed up error printing.  */
-         static char line[MAX_ERROR_MESSAGE + 1];
-         static int index = 0;
+         static char *line;
+         static size_t allocated = 0, index = 0;
 
+         if (index + 1 >= allocated)
+           {
+             allocated = allocated ? allocated * 2 : 1000;
+             line = xrealloc (line, allocated);
+           }
          line[index++] = c;
-         if (c == '\n' || index == MAX_ERROR_MESSAGE)
+         if (c == '\n')
            {
              line[index] = '\0';
              fputs (line, stderr);
@@ -470,8 +470,8 @@ gfc_warning (const char *format, ...)
     return;
 
   warning_buffer.flag = 1;
-  warning_ptr = warning_buffer.message;
-  use_warning_buffer = 1;
+  warning_buffer.index = 0;
+  cur_error_buffer = &warning_buffer;
 
   va_start (argp, format);
   if (buffer_flag == 0)
@@ -503,18 +503,9 @@ gfc_notify_std (int std, const char *format, ...)
   if (gfc_suppress_error)
     return warning ? SUCCESS : FAILURE;
   
-  if (warning)
-    {
-      warning_buffer.flag = 1;
-      warning_ptr = warning_buffer.message;
-      use_warning_buffer = 1;
-    }
-  else
-    {
-      error_buffer.flag = 1;
-      error_ptr = error_buffer.message;
-      use_warning_buffer = 0;
-    }
+  cur_error_buffer = warning ? &warning_buffer : &error_buffer;
+  cur_error_buffer->flag = 1;
+  cur_error_buffer->index = 0;
 
   if (buffer_flag == 0)
     {
@@ -577,7 +568,8 @@ gfc_warning_check (void)
   if (warning_buffer.flag)
     {
       warnings++;
-      fputs (warning_buffer.message, stderr);
+      if (warning_buffer.message != NULL)
+       fputs (warning_buffer.message, stderr);
       warning_buffer.flag = 0;
     }
 }
@@ -594,8 +586,8 @@ gfc_error (const char *format, ...)
     return;
 
   error_buffer.flag = 1;
-  error_ptr = error_buffer.message;
-  use_warning_buffer = 0;
+  error_buffer.index = 0;
+  cur_error_buffer = &error_buffer;
 
   va_start (argp, format);
   if (buffer_flag == 0)
@@ -616,7 +608,8 @@ gfc_error_now (const char *format, ...)
   int i;
 
   error_buffer.flag = 1;
-  error_ptr = error_buffer.message;
+  error_buffer.index = 0;
+  cur_error_buffer = &error_buffer;
 
   i = buffer_flag;
   buffer_flag = 0;
@@ -691,7 +684,8 @@ gfc_error_check (void)
   if (error_buffer.flag)
     {
       errors++;
-      fputs (error_buffer.message, stderr);
+      if (error_buffer.message != NULL)
+       fputs (error_buffer.message, stderr);
       error_buffer.flag = 0;
     }
 
@@ -706,7 +700,7 @@ gfc_push_error (gfc_error_buf * err)
 {
   err->flag = error_buffer.flag;
   if (error_buffer.flag)
-    strcpy (err->message, error_buffer.message);
+    err->message = xstrdup (error_buffer.message);
 
   error_buffer.flag = 0;
 }
@@ -719,7 +713,22 @@ gfc_pop_error (gfc_error_buf * err)
 {
   error_buffer.flag = err->flag;
   if (error_buffer.flag)
-    strcpy (error_buffer.message, err->message);
+    {
+      size_t len = strlen (err->message) + 1;
+      gcc_assert (len <= error_buffer.allocated);
+      memcpy (error_buffer.message, err->message, len);
+      gfc_free (err->message);
+    }
+}
+
+
+/* Free a pushed error state, but keep the current error state.  */
+
+void
+gfc_free_error (gfc_error_buf * err)
+{
+  if (err->flag)
+    gfc_free (err->message);
 }
 
 
index 71b6c19b9325416980340e6784dbac16a0344094..dea08c3e20de9d5310a6f59fec128f512b330ee1 100644 (file)
@@ -58,7 +58,6 @@ char *alloca ();
 #define GFC_MAX_LINE 132       /* Characters beyond this are not seen.  */
 #define GFC_MAX_DIMENSIONS 7   /* Maximum dimensions in an array.  */
 #define GFC_LETTERS 26         /* Number of letters in the alphabet.  */
-#define MAX_ERROR_MESSAGE 1000 /* Maximum length of an error message.  */
 
 #define free(x) Use_gfc_free_instead_of_free()
 #define gfc_is_whitespace(c) ((c==' ') || (c=='\t'))
@@ -1548,7 +1547,8 @@ const char * gfc_get_string (const char *, ...) ATTRIBUTE_PRINTF_1;
 typedef struct gfc_error_buf
 {
   int flag;
-  char message[MAX_ERROR_MESSAGE];
+  size_t allocated, index;
+  char *message;
 } gfc_error_buf;
 
 void gfc_error_init_1 (void);
@@ -1574,6 +1574,7 @@ try gfc_notify_std (int, const char *, ...) ATTRIBUTE_GCC_GFC(2,3);
 
 void gfc_push_error (gfc_error_buf *);
 void gfc_pop_error (gfc_error_buf *);
+void gfc_free_error (gfc_error_buf *);
 
 void gfc_status (const char *, ...) ATTRIBUTE_PRINTF_1;
 void gfc_status_char (char);
index f63eaf6bed3a192c45a17af41c41836d21f5a224..7f249eecf10e01df60dba94b7b79515fcd5a6963 100644 (file)
@@ -2650,6 +2650,8 @@ gfc_match_st_function (void)
   m = gfc_match (" = %e%t", &expr);
   if (m == MATCH_NO)
     goto undo_error;
+
+  gfc_free_error (&old_error);
   if (m == MATCH_ERROR)
     return m;
 
index 36e5eb96f37c65e375cf225ec0d16d58d4e642b9..888caffa5c281748b402eeefa2ceea9457f68e67 100644 (file)
@@ -1117,7 +1117,10 @@ match_complex_constant (gfc_expr ** result)
 
   m = match_complex_part (&real);
   if (m == MATCH_NO)
-    goto cleanup;
+    {
+      gfc_free_error (&old_error);
+      goto cleanup;
+    }
 
   if (gfc_match_char (',') == MATCH_NO)
     {
@@ -1132,7 +1135,10 @@ match_complex_constant (gfc_expr ** result)
      sort. These sort of lists are matched prior to coming here.  */
 
   if (m == MATCH_ERROR)
-    goto cleanup;
+    {
+      gfc_free_error (&old_error);
+      goto cleanup;
+    }
   gfc_pop_error (&old_error);
 
   m = match_complex_part (&imag);
index d0c2c653efab2fdf402bd25b3d8dd05c3e40ce48..334e96e46385cabef4161288a45174506393ce0f 100644 (file)
@@ -1,5 +1,7 @@
 2005-07-14  Jakub Jelinek  <jakub@redhat.com>
 
+       * gfortran.dg/g77/cpp6.f: New test.
+
        PR fortran/22417
        * gfortran.dg/g77/cpp5.F: New test.
        * gfortran.dg/g77/cpp5.h: New file.
diff --git a/gcc/testsuite/gfortran.dg/g77/cpp6.f b/gcc/testsuite/gfortran.dg/g77/cpp6.f
new file mode 100644 (file)
index 0000000..5f973c1
--- /dev/null
@@ -0,0 +1,20 @@
+# 1 "test.F"
+# 1 "<built-in>"
+# 1 "<command line>"
+# 1 "test.F"
+       ! { dg-do compile }
+
+# 1 "A234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+
+# 1 "B234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+
+# 1 "C234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+
+# 1 "D234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+       PARAMETER (I=1)
+
+# 2 "C234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 2
+# 2 "B234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 2
+# 2 "A234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 2
+# 3 "test.F" 2
+       END