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]

PATCH: [cpplib] fix PR/34869


line5.c in CPP testsuite under valgrind shows several errors, the first being

Executing on host: /tmp/hptest8/obj/gcc/xgcc -B/tmp/hptest8/obj/gcc/
/tmp/hptest8/gcc/gcc/testsuite/gcc.dg/cpp/line5.c   -fpreproc
essed -fno-show-column -E  -o line5.i    (timeout = 300)
==24251== Conditional jump or move depends on uninitialised value(s)
==24251==    at 0x92D27B: _cpp_lex_token (lex.c:783)
==24251==    by 0x92F6FC: cpp_get_token (macro.c:1110)
==24251==    by 0x4499B7: preprocess_file (c-ppoutput.c:148)
==24251==    by 0x4422C0: c_common_init (c-opts.c:1237)
==24251==    by 0x44C21D: c_objc_common_init (c-objc-common.c:72)
==24251==    by 0x5F5FA7: toplev_main (toplev.c:2128)
==24251==    by 0x387301E073: (below main) (in /lib64/libc-2.7.so)

Immediate cause for it is that _cpp_lex_token tries to get the next
lookahead token and receives uninitialized memory for it. A sequence
of calls leading to this is (from printf debugging):

Entered read_original_filename
_cpp_lex_direct called
_cpp_lex_direct called
_cpp_backup_tokens_direct called, count = 1
Using up lookahead token
_cpp_backup_tokens_direct called, count = 1
_cpp_lex_direct called
_cpp_backup_tokens_direct called, count = 1
Left read_original_filename in the middle
Using up lookahead token
Using up lookahead token <- uninitialized memory here.

Note that after second _cpp_backup_tokens_direct call we have one
lookahead token available, yet there is a _cpp_lex_direct call which
lexes ahead instead of consuming available token. This call is a first
call in read_original_directory. If it is replaced by the code that
consumes lookahead token if available, then the bug disappears.

Of course, checking for lookahead tokens in just one _cpp_lex_direct
call site out of many seems suspicious, although this situation almost
never arises (I have checked that in the whole cpp testsuite only
line5.c causes _cpp_lex_direct invocation with lookahead token
available). So I have decided to move lookahead handling from
_cpp_lex_token to _cpp_lex_direct.

Bootstrapped/regtested on x86_64-unknown-linux-gnu, no regressions.

OK for trunk?

Thanks.

-- 
Laurynas


2009-04-24  Laurynas Biveinis  <laurynas.biveinis@gmail.com>

	PR preprocessor/34869
	* lex.c (_cpp_lex_token): Remove lookadhead token handling.
	(_cpp_lex_direct): Handle lookahead tokens.


Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(revision 146637)
+++ libcpp/lex.c	(working copy)
@@ -880,8 +880,8 @@
 }

 /* Lex a token into RESULT (external interface).  Takes care of issues
-   like directive handling, token lookahead, multiple include
-   optimization and skipping.  */
+   like directive handling, multiple include optimization and
+   skipping.  */
 const cpp_token *
 _cpp_lex_token (cpp_reader *pfile)
 {
@@ -900,13 +900,7 @@
 	  || pfile->cur_token >= pfile->cur_run->limit)
 	abort ();

-      if (pfile->lookaheads)
-	{
-	  pfile->lookaheads--;
-	  result = pfile->cur_token++;
-	}
-      else
-	result = _cpp_lex_direct (pfile);
+      result = _cpp_lex_direct (pfile);

       if (result->flags & BOL)
 	{
@@ -1003,10 +997,11 @@
 /* Lex a token into pfile->cur_token, which is also incremented, to
    get diagnostics pointing to the correct location.

-   Does not handle issues such as token lookahead, multiple-include
-   optimization, directives, skipping etc.  This function is only
-   suitable for use by _cpp_lex_token, and in special cases like
-   lex_expansion_token which doesn't care for any of these issues.
+   Is able to handle token lookahead, but does not handle issues such
+   as multiple-include optimization, directives, skipping etc.  This
+   function is only suitable for use by _cpp_lex_token, and in special
+   cases like lex_expansion_token which doesn't care for any of these
+   issues.

    When meeting a newline, returns CPP_EOF if parsing a directive,
    otherwise returns to the start of the token buffer if permissible.
@@ -1019,6 +1014,12 @@
   const unsigned char *comment_start;
   cpp_token *result = pfile->cur_token++;

+  if (pfile->lookaheads)
+    {
+      pfile->lookaheads--;
+      return result;
+    }
+
  fresh_line:
   result->flags = 0;
   buffer = pfile->buffer;


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