Patch for C++ bug 24009

Joseph S. Myers joseph@codesourcery.com
Sat Aug 26 14:09:00 GMT 2006


This patch fixes bug 24009, C++ diagnostics no longer reporting the
#include stack since the move to lexing up front, by saving and
restoring the input file stack.  There are conveniently 31 bits free
in the cp_token structure to keep track of the include state for each
token.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
commit?

(It doesn't seem readily possible to put this sort of test in the
testsuite, but I've checked by hand that the tests from comment#2 and
comment#3 now work.)

2006-08-25  Joseph S. Myers  <joseph@codesourcery.com>

	PR c++/24009
	* input.h (restore_input_file_stack): Declare.
	* toplev.c (fs_p, input_file_stack_history,
	input_file_stack_restored, restore_input_file_stack): New.
	(push_srcloc, pop_srcloc): Check for input_file_stack_tick
	overflowing 31 bits.  Save new state of stack.
	(pop_srcloc): Don't free old state of stack.

cp:
2006-08-25  Joseph S. Myers  <joseph@codesourcery.com>

	PR c++/24009
	* parser.c (struct cp_token): Add input_file_stack_index.
	(eof_token): Update.
	(cp_lexer_get_preprocessor_token): Save input_file_stack_tick.
	(cp_lexer_set_source_position_from_token): Restore input file
	stack.

diff -rupN GCC.orig/gcc/cp/parser.c GCC/gcc/cp/parser.c
--- GCC.orig/gcc/cp/parser.c	2006-08-23 11:19:33.000000000 +0000
+++ GCC/gcc/cp/parser.c	2006-08-26 00:18:52.000000000 +0000
@@ -66,6 +66,8 @@ typedef struct cp_token GTY (())
      KEYWORD is RID_MAX) iff this name was looked up and found to be
      ambiguous.  An error has already been reported.  */
   BOOL_BITFIELD ambiguous_p : 1;
+  /* The input file stack index at which this token was found.  */
+  unsigned input_file_stack_index : 31;
   /* The value associated with this token, if any.  */
   tree value;
   /* The location at which this token was found.  */
@@ -79,7 +81,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap)
 
 static const cp_token eof_token =
 {
-  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, NULL_TREE,
+  CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, 0, NULL_TREE,
 #if USE_MAPPED_LOCATION
   0
 #else
@@ -393,6 +395,7 @@ cp_lexer_get_preprocessor_token (cp_lexe
    /* Get a new token from the preprocessor.  */
   token->type
     = c_lex_with_flags (&token->value, &token->location, &token->flags);
+  token->input_file_stack_index = input_file_stack_tick;
   token->keyword = RID_MAX;
   token->pragma_kind = PRAGMA_NONE;
   token->in_system_header = in_system_header;
@@ -450,7 +453,8 @@ cp_lexer_get_preprocessor_token (cp_lexe
     }
 }
 
-/* Update the globals input_location and in_system_header from TOKEN.  */
+/* Update the globals input_location and in_system_header and the
+   input file stack from TOKEN.  */
 static inline void
 cp_lexer_set_source_position_from_token (cp_token *token)
 {
@@ -458,6 +462,7 @@ cp_lexer_set_source_position_from_token 
     {
       input_location = token->location;
       in_system_header = token->in_system_header;
+      restore_input_file_stack (token->input_file_stack_index);
     }
 }
 
diff -rupN GCC.orig/gcc/input.h GCC/gcc/input.h
--- GCC.orig/gcc/input.h	2005-10-28 23:34:10.000000000 +0000
+++ GCC/gcc/input.h	2006-08-25 23:34:52.000000000 +0000
@@ -84,6 +84,7 @@ extern void push_srcloc (location_t);
 extern void push_srcloc (const char *name, int line);
 #endif /* ! USE_MAPPED_LOCATION */
 extern void pop_srcloc (void);
+extern void restore_input_file_stack (int);
 
 #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
 #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
diff -rupN GCC.orig/gcc/toplev.c GCC/gcc/toplev.c
--- GCC.orig/gcc/toplev.c	2006-08-02 09:04:23.000000000 +0000
+++ GCC/gcc/toplev.c	2006-08-25 23:38:04.000000000 +0000
@@ -164,6 +164,16 @@ struct file_stack *input_file_stack;
 /* Incremented on each change to input_file_stack.  */
 int input_file_stack_tick;
 
+/* Record of input_file_stack at each tick.  */
+typedef struct file_stack *fs_p;
+DEF_VEC_P(fs_p);
+DEF_VEC_ALLOC_P(fs_p,heap);
+static VEC(fs_p,heap) *input_file_stack_history;
+
+/* Whether input_file_stack has been restored to a previous state (in
+   which case there should be no more pushing).  */
+static bool input_file_stack_restored;
+
 /* Name to use as base of names for dump output files.  */
 
 const char *dump_base_name;
@@ -951,6 +961,10 @@ push_srcloc (const char *file, int line)
 {
   struct file_stack *fs;
 
+  gcc_assert (!input_file_stack_restored);
+  if (input_file_stack_tick == 0x7fffffff)
+    sorry ("GCC supports only %d input file changes", input_file_stack_tick);
+
   fs = XNEW (struct file_stack);
   fs->location = input_location;
   fs->next = input_file_stack;
@@ -962,6 +976,7 @@ push_srcloc (const char *file, int line)
 #endif
   input_file_stack = fs;
   input_file_stack_tick++;
+  VEC_safe_push (fs_p, heap, input_file_stack_history, input_file_stack);
 }
 
 /* Pop the top entry off the stack of presently open source files.
@@ -973,11 +988,30 @@ pop_srcloc (void)
 {
   struct file_stack *fs;
 
+  gcc_assert (!input_file_stack_restored);
+  if (input_file_stack_tick == 0x7fffffff)
+    sorry ("GCC supports only %d input file changes", input_file_stack_tick);
+
   fs = input_file_stack;
   input_location = fs->location;
   input_file_stack = fs->next;
-  free (fs);
   input_file_stack_tick++;
+  VEC_safe_push (fs_p, heap, input_file_stack_history, input_file_stack);
+}
+
+/* Restore the input file stack to its state as of TICK, for the sake
+   of diagnostics after processing the whole input.  Once this has
+   been called, push_srcloc and pop_srcloc may no longer be
+   called.  */
+void
+restore_input_file_stack (int tick)
+{
+  if (tick == 0)
+    input_file_stack = NULL;
+  else
+    input_file_stack = VEC_index (fs_p, input_file_stack_history, tick - 1);
+  input_file_stack_tick = tick;
+  input_file_stack_restored = true;
 }
 
 /* Compile an entire translation unit.  Write a file of assembly

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Gcc-patches mailing list