summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-22 11:42:30 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-22 11:42:30 +0000
commitda4e72c7fe35d5895fbc8b90d4c777d1a703143c (patch)
treeeec4e88cf5defc14069be13e67e934ba7f9b5a69
parentaa8fd7bcbc0d7e854395c3242ff86b771f4cf790 (diff)
downloadgcc-da4e72c7fe35d5895fbc8b90d4c777d1a703143c.tar.gz
cp:
PR c++/18095 * parser.c (eof_token): Make const, correctly initialize rid and location fields. (struct cp_lexer): Replace buffer_end pointer with buffer_length count. Adjust. (cp_lexer_new_main): Directly grow lexer's buffer here. Don't zero it out. (cp_lexer_new_from_tokens): Adjust. (cp_lexer_grow_buffer): Remove. (cp_lexer_peek_nth_token, cp_lexer_consume_token, cp_lexer_purge_token): Add const casts. testsuite: PR c++/18095 * g++.dg/parse/crash18.C: New. * g++.dg/parse/crash19.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89439 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/parser.c115
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/parse/crash18.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/crash19.C7
5 files changed, 85 insertions, 64 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2c78f23b265..b5dae4983e1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2004-10-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18095
+ * parser.c (eof_token): Make const, correctly initialize rid and
+ location fields.
+ (struct cp_lexer): Replace buffer_end pointer with buffer_length
+ count. Adjust.
+ (cp_lexer_new_main): Directly grow lexer's buffer here. Don't
+ zero it out.
+ (cp_lexer_new_from_tokens): Adjust.
+ (cp_lexer_grow_buffer): Remove.
+ (cp_lexer_peek_nth_token, cp_lexer_consume_token,
+ cp_lexer_purge_token): Add const casts.
+
2004-10-21 Mark Mitchell <mark@codesourcery.com>
PR c++/18073
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index fc947a5936f..7109862b2dd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -67,7 +67,15 @@ typedef struct cp_token GTY (())
typedef struct cp_token *cp_token_position;
DEF_VEC_MALLOC_P (cp_token_position);
-static cp_token eof_token = {CPP_EOF, 0, 0, 0, 0, NULL_TREE, {0, 0}};
+static const cp_token eof_token =
+{
+ CPP_EOF, RID_MAX, 0, 0, 0, NULL_TREE,
+#if USE_MAPPED_LOCATION
+ 0
+#else
+ {0, 0}
+#endif
+};
/* The cp_lexer structure represents the C++ lexer. It is responsible
for managing the token stream from the preprocessor and supplying
@@ -78,10 +86,10 @@ typedef struct cp_lexer GTY (())
{
/* The memory allocated for the buffer. NULL if this lexer does not
own the token buffer. */
- cp_token * GTY ((length ("(%h.buffer_end - %h.buffer)"))) buffer;
- /* If non-null, a pointer just past the end of the memory allocated
- for the buffer. */
- cp_token * GTY ((skip)) buffer_end;
+ cp_token * GTY ((length ("%h.buffer_length"))) buffer;
+ /* If the lexer owns the buffer, this is the number of tokens in the
+ buffer. */
+ size_t buffer_length;
/* A pointer just past the last available token. The tokens
in this lexer are [buffer, last_token). */
@@ -133,8 +141,6 @@ static cp_token_position cp_lexer_token_position
(cp_lexer *, bool);
static cp_token *cp_lexer_token_at
(cp_lexer *, cp_token_position);
-static void cp_lexer_grow_buffer
- (cp_lexer *);
static void cp_lexer_get_preprocessor_token
(cp_lexer *, cp_token *);
static inline cp_token *cp_lexer_peek_token
@@ -224,8 +230,12 @@ static FILE *cp_lexer_debug_stream;
static cp_lexer *
cp_lexer_new_main (void)
{
- cp_lexer *lexer;
cp_token first_token;
+ cp_lexer *lexer;
+ cp_token *pos;
+ size_t alloc;
+ size_t space;
+ cp_token *buffer;
/* Tell cpplib we want CPP_PRAGMA tokens. */
cpp_get_options (parse_in)->defer_pragmas = true;
@@ -242,30 +252,38 @@ cp_lexer_new_main (void)
/* Allocate the memory. */
lexer = GGC_CNEW (cp_lexer);
- /* Create the buffer. */
- lexer->buffer = ggc_calloc (CP_LEXER_BUFFER_SIZE, sizeof (cp_token));
- lexer->buffer_end = lexer->buffer + CP_LEXER_BUFFER_SIZE;
-
- /* There is one token in the buffer. */
- lexer->last_token = lexer->buffer;
- lexer->next_token = lexer->buffer;
- *lexer->next_token = first_token;
-
- lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
-
#ifdef ENABLE_CHECKING
/* Initially we are not debugging. */
lexer->debugging_p = false;
#endif /* ENABLE_CHECKING */
+ lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
+
+ /* Create the buffer. */
+ alloc = CP_LEXER_BUFFER_SIZE;
+ buffer = ggc_alloc (alloc * sizeof (cp_token));
- /* Get the rest of the tokens from the preprocessor. */
- while (lexer->last_token->type != CPP_EOF)
+ /* Put the first token in the buffer. */
+ space = alloc;
+ pos = buffer;
+ *pos = first_token;
+
+ /* Get the remaining tokens from the preprocessor. */
+ while (pos->type != CPP_EOF)
{
- lexer->last_token++;
- if (lexer->last_token == lexer->buffer_end)
- cp_lexer_grow_buffer (lexer);
- cp_lexer_get_preprocessor_token (lexer, lexer->last_token);
+ pos++;
+ if (!--space)
+ {
+ space = alloc;
+ alloc *= 2;
+ buffer = ggc_realloc (buffer, alloc * sizeof (cp_token));
+ pos = buffer + space;
+ }
+ cp_lexer_get_preprocessor_token (lexer, pos);
}
+ lexer->buffer = buffer;
+ lexer->buffer_length = alloc - space;
+ lexer->last_token = pos;
+ lexer->next_token = lexer->buffer_length ? buffer : (cp_token *)&eof_token;
/* Pragma processing (via cpp_handle_deferred_pragma) may result in
direct calls to c_lex. Those callers all expect c_lex to do
@@ -287,8 +305,9 @@ cp_lexer_new_from_tokens (cp_token_cache *cache)
cp_lexer *lexer = GGC_CNEW (cp_lexer);
/* We do not own the buffer. */
- lexer->buffer = lexer->buffer_end = NULL;
- lexer->next_token = first == last ? &eof_token : first;
+ lexer->buffer = NULL;
+ lexer->buffer_length = 0;
+ lexer->next_token = first == last ? (cp_token *)&eof_token : first;
lexer->last_token = last;
lexer->saved_tokens = VEC_alloc (cp_token_position, CP_SAVED_TOKEN_STACK);
@@ -347,40 +366,8 @@ cp_lexer_saving_tokens (const cp_lexer* lexer)
return VEC_length (cp_token_position, lexer->saved_tokens) != 0;
}
-/* If the buffer is full, make it bigger. */
-static void
-cp_lexer_grow_buffer (cp_lexer* lexer)
-{
- cp_token *old_buffer;
- cp_token *new_buffer;
- ptrdiff_t buffer_length;
-
- /* This function should only be called when buffer is full. */
- gcc_assert (lexer->last_token == lexer->buffer_end);
-
- /* Remember the current buffer pointer. It will become invalid,
- but we will need to do pointer arithmetic involving this
- value. */
- old_buffer = lexer->buffer;
- /* Compute the current buffer size. */
- buffer_length = lexer->buffer_end - lexer->buffer;
- /* Allocate a buffer twice as big. */
- new_buffer = ggc_realloc (lexer->buffer,
- 2 * buffer_length * sizeof (cp_token));
-
- /* Recompute buffer positions. */
- lexer->buffer = new_buffer;
- lexer->buffer_end = new_buffer + 2 * buffer_length;
- lexer->last_token = new_buffer + (lexer->last_token - old_buffer);
- lexer->next_token = new_buffer + (lexer->next_token - old_buffer);
-
- /* Clear the rest of the buffer. We never look at this storage,
- but the garbage collector may. */
- memset (lexer->last_token, 0,
- (lexer->buffer_end - lexer->last_token) * sizeof(cp_token));
-}
-
-/* Store the next token from the preprocessor in *TOKEN. */
+/* Store the next token from the preprocessor in *TOKEN. Return true
+ if we reach EOF. */
static void
cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
@@ -519,7 +506,7 @@ cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
++token;
if (token == lexer->last_token)
{
- token = &eof_token;
+ token = (cp_token *)&eof_token;
break;
}
@@ -551,7 +538,7 @@ cp_lexer_consume_token (cp_lexer* lexer)
lexer->next_token++;
if (lexer->next_token == lexer->last_token)
{
- lexer->next_token = &eof_token;
+ lexer->next_token = (cp_token *)&eof_token;
break;
}
@@ -591,7 +578,7 @@ cp_lexer_purge_token (cp_lexer *lexer)
tok++;
if (tok == lexer->last_token)
{
- tok = &eof_token;
+ tok = (cp_token *)&eof_token;
break;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 676d8a6026a..205676bc04b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2004-10-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18095
+ * g++.dg/parse/crash18.C: New.
+ * g++.dg/parse/crash19.C: New.
+
2004-10-22 Aaron W. LaFramboise <aaronavay62@aaronwl.com>
* g++.dg/ext/dllimport1.C: Move dg-warnings.
diff --git a/gcc/testsuite/g++.dg/parse/crash18.C b/gcc/testsuite/g++.dg/parse/crash18.C
new file mode 100644
index 00000000000..94be360ab1d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash18.C
@@ -0,0 +1,7 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 20 Oct 2004 <nathan@codesourcery.com>
+
+// PR 18095: ICE
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+
+struct A // { dg-error "expected" "" }
diff --git a/gcc/testsuite/g++.dg/parse/crash19.C b/gcc/testsuite/g++.dg/parse/crash19.C
new file mode 100644
index 00000000000..cc50d9507e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash19.C
@@ -0,0 +1,7 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 20 Oct 2004 <nathan@codesourcery.com>
+
+// PR 18095: ICE
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+
+struct A {} // { dg-error "expected" "" }