aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-14 10:12:17 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-14 10:12:17 +0000
commit19895fc10b2219ca4c49de5d99ba73d3a024fbc9 (patch)
treec2963bb336cabb4f3f780c2faf9a7041c131dbc1
parent70e9546799274a3efa8e96e77dc681a62082bb9e (diff)
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102015 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog20
-rw-r--r--gcc/fortran/error.c87
-rw-r--r--gcc/fortran/gfortran.h5
-rw-r--r--gcc/fortran/match.c2
-rw-r--r--gcc/fortran/primary.c10
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/gfortran.dg/g77/cpp6.f20
7 files changed, 103 insertions, 43 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 5f17e5edc6b..8fd316abb0f 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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.
diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index fe7decc5dfb..009419a0979 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -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);
}
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 71b6c19b932..dea08c3e20d 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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);
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index f63eaf6bed3..7f249eecf10 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -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;
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 36e5eb96f37..888caffa5c2 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0c2c653efa..334e96e4638 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..5f973c15b2b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/g77/cpp6.f
@@ -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