This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[pph] Clear lexer state while replaying the symbol table (issue5645047)


When we re-play the symbol table for a PPH image, we are executing
from libcpp's #include handler.  This means that the lexer thinks that
it is inside the #include directive.

This alters the lexer behaviour in subtle ways.  In this test case,
for example, the parsing of the escaped quotes inside the asm()
instruction makes the lexer think that the string has ended before it
actually does.

This cascades into a lexing or syntax error later on because the
string got truncated.

This patch saves and restores the lexer state as we re-play the symbol
table.  Initially, I was trying to do this after we return from the
table are needed while we read the PPH file.

2012-02-06   Diego Novillo  <dnovillo@google.com>

libcpp/ChangeLog.pph
	* directives.c (_cpp_clear_directive_state): New.
	(end_directive): Call it.
	(_cpp_save_directive_state): New.
	(_cpp_restore_directive_state): New.
	* internal.h (_cpp_clear_directive_state): Declare.
	(_cpp_save_directive_state): Declare.
	(_cpp_restore_directive_state): Declare.
	* symtab.c (cpp_lt_replay): Call
	_cpp_clear_directive_state, _cpp_save_directive_state and
	_cpp_restore_directive_state.

gcc/testsuite/ChangeLog.pph
	* g++.dg/pph/x0string-escapes.h: New.
	* g++.dg/pph/x1string-escapes.h: New.
	* g++.dg/pph/x2string-escapes.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/pph@183952 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/testsuite/ChangeLog.pph                  |    6 ++++
 gcc/testsuite/g++.dg/pph/x0string-escapes.h  |    7 ++++
 gcc/testsuite/g++.dg/pph/x1string-escapes.h  |    4 ++
 gcc/testsuite/g++.dg/pph/x2string-escapes.cc |    9 +++++
 libcpp/ChangeLog.pph                         |   13 ++++++++
 libcpp/directives.c                          |   42 ++++++++++++++++++++++---
 libcpp/internal.h                            |    6 ++++
 libcpp/symtab.c                              |   11 +++++++
 8 files changed, 93 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pph/x0string-escapes.h
 create mode 100644 gcc/testsuite/g++.dg/pph/x1string-escapes.h
 create mode 100644 gcc/testsuite/g++.dg/pph/x2string-escapes.cc

diff --git a/gcc/testsuite/ChangeLog.pph b/gcc/testsuite/ChangeLog.pph
index 4037c01..3248e91 100644
--- a/gcc/testsuite/ChangeLog.pph
+++ b/gcc/testsuite/ChangeLog.pph
@@ -1,3 +1,9 @@
+2012-02-06   Diego Novillo  <dnovillo@google.com>
+
+	* g++.dg/pph/x0string-escapes.h: New.
+	* g++.dg/pph/x1string-escapes.h: New.
+	* g++.dg/pph/x2string-escapes.cc: New.
+
 2012-02-01   Lawrence Crowl  <crowl@google.com>
 
 	* g++.dg/pph/x4structover1.cc: Mark fixed.
diff --git a/gcc/testsuite/g++.dg/pph/x0string-escapes.h b/gcc/testsuite/g++.dg/pph/x0string-escapes.h
new file mode 100644
index 0000000..92db6bc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/x0string-escapes.h
@@ -0,0 +1,7 @@
+#ifndef X0_STRING_ESCAPES_H
+#define X0_STRING_ESCAPES_H
+#define FOO(s) \
+  asm(".pushsection \".section_name\", \"MS\",%progbits,1\n" \
+      ".asciz \"" s "\"\n" \
+      ".popsection \n");
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/x1string-escapes.h b/gcc/testsuite/g++.dg/pph/x1string-escapes.h
new file mode 100644
index 0000000..2539688
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/x1string-escapes.h
@@ -0,0 +1,4 @@
+#ifndef X1_STRING_ESCAPES_H
+#define X1_STRING_ESCAPES_H
+#include "x0string-escapes.h"
+#endif
diff --git a/gcc/testsuite/g++.dg/pph/x2string-escapes.cc b/gcc/testsuite/g++.dg/pph/x2string-escapes.cc
new file mode 100644
index 0000000..511f7b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pph/x2string-escapes.cc
@@ -0,0 +1,9 @@
+#include "x1string-escapes.h"
+
+int foo(int);
+
+int foo(int i)
+{
+  FOO("name");
+  return i;
+}
diff --git a/libcpp/ChangeLog.pph b/libcpp/ChangeLog.pph
index a74344f..37216a4 100644
--- a/libcpp/ChangeLog.pph
+++ b/libcpp/ChangeLog.pph
@@ -1,3 +1,16 @@
+2012-02-06   Diego Novillo  <dnovillo@google.com>
+
+	* directives.c (_cpp_clear_directive_state): New.
+	(end_directive): Call it.
+	(_cpp_save_directive_state): New.
+	(_cpp_restore_directive_state): New.
+	* internal.h (_cpp_clear_directive_state): Declare.
+	(_cpp_save_directive_state): Declare.
+	(_cpp_restore_directive_state): Declare.
+	* symtab.c (cpp_lt_replay): Call
+	_cpp_clear_directive_state, _cpp_save_directive_state and
+	_cpp_restore_directive_state.
+
 2012-01-18   Diego Novillo  <dnovillo@google.com>
 
 	* internal.h (cpp_in_primary_file): Move ...
diff --git a/libcpp/directives.c b/libcpp/directives.c
index ecd1486..043d602 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -311,11 +311,7 @@ end_directive (cpp_reader *pfile, int skip_line)
     }
 
   /* Restore state.  */
-  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
-  pfile->state.in_directive = 0;
-  pfile->state.in_expression = 0;
-  pfile->state.angled_headers = 0;
-  pfile->directive = 0;
+  _cpp_clear_directive_state (pfile);
 }
 
 /* Prepare to handle the directive in pfile->directive.  */
@@ -2606,3 +2602,39 @@ _cpp_init_directives (cpp_reader *pfile)
       node->directive_index = i;
     }
 }
+
+/* Clear lexer directive state for PFILE.  */
+
+void
+_cpp_clear_directive_state (cpp_reader *pfile)
+{
+  pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
+  pfile->state.in_directive = 0;
+  pfile->state.in_expression = 0;
+  pfile->state.angled_headers = 0;
+  pfile->directive = 0;
+}
+
+
+/* Save lexer directive state for PFILE on *DIRECTIVE_P and *STATE_P.  */
+
+void
+_cpp_save_directive_state (cpp_reader *pfile,
+			   const struct directive **directive_p,
+			   struct lexer_state *state_p)
+{
+  memcpy (state_p, &pfile->state, sizeof (*state_p));
+  *directive_p = pfile->directive;
+}
+
+
+/* Restore lexer directive state for PFILE from *DIRECTIVE_P and *STATE_P.  */
+
+void
+_cpp_restore_directive_state (cpp_reader *pfile,
+			      const struct directive *directive_p,
+			      struct lexer_state *state_p)
+{
+  memcpy (&pfile->state, state_p, sizeof (*state_p));
+  pfile->directive = directive_p;
+}
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 9b35507..63139de 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -719,6 +719,12 @@ extern void _cpp_init_internal_pragmas (cpp_reader *);
 extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
 				 linenum_type, unsigned int);
 extern void _cpp_pop_buffer (cpp_reader *);
+extern void _cpp_clear_directive_state (cpp_reader *);
+extern void _cpp_save_directive_state (cpp_reader *, const struct directive **,
+				       struct lexer_state *);
+extern void _cpp_restore_directive_state (cpp_reader *,
+					  const struct directive *,
+					  struct lexer_state *);
 
 /* In directives.c */
 struct _cpp_dir_only_callbacks
diff --git a/libcpp/symtab.c b/libcpp/symtab.c
index a0b5e84..63e76fd 100644
--- a/libcpp/symtab.c
+++ b/libcpp/symtab.c
@@ -825,6 +825,8 @@ void
 cpp_lt_replay (cpp_reader *reader, cpp_idents_used* identifiers,
                source_location *loc)
 {
+  const struct directive *directive;
+  struct lexer_state state;
   unsigned int i;
   unsigned int num_entries = identifiers->num_entries;
   cpp_ident_use *entries = identifiers->entries;
@@ -834,6 +836,12 @@ cpp_lt_replay (cpp_reader *reader, cpp_idents_used* identifiers,
   /* Prevent the lexer from invalidating the tokens we've read so far.  */
   reader->keep_tokens++;
 
+  /* Clear the lexer state so it does not think that we are inside a
+     directive.  When re-playing the symbol table, we are inside the
+     #include directive that brought in a PPH image.  */
+  _cpp_save_directive_state (reader, &directive, &state);
+  _cpp_clear_directive_state (reader);
+
   if (loc)
     cpp_force_token_locations (reader, loc);
 
@@ -874,6 +882,9 @@ cpp_lt_replay (cpp_reader *reader, cpp_idents_used* identifiers,
     cpp_stop_forcing_token_locations (reader);
 
   free (buffer);
+
+  /* Restore the lexer state.  */
+  _cpp_restore_directive_state (reader, directive, &state);
 }
 
 /* Destroy IDENTIFIERS captured.  */
-- 
1.7.7.3


--
This patch is available for review at http://codereview.appspot.com/5645047


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]