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]

cpplib: small buffer / file handling improvement


This patch

o Pushes a zero-length buffer on cpplib's buffer stack, instead of pushing
  no buffer at all, when we have an error reading / opening the file, or
  a zero-length file, or the file has been marked not to be reread for
  any other reason.

o Moves the test for #include recursion to the common #include handler,
  rather than cpp_push_buffer.  This avoids innocent victims of this
  check, such as _Pragma.

o Similarly moves another ICE check to the #include handler where it more
  properly belongs.

These changes mean that some internal functions that used to return
error codes, such as stack_include_file, can no longer fail, so they
return void instead.  A buffer is stacked no matter what.

This state of affairs is still not perfect, but better than the
current situation where the caller can be expecting a buffer to have
been stacked but it hasn't (even in non-error conditions like
zero-length files).  I hope this cures the failures on zero-length
files with integrated cpp.

Neil.

	* cppfiles.c (stack_include_file): Push zero-length buffers
	in case of failure.  Return void, as we don't fail any more.
	(read_include_file): Check for files we shouldn't re-read.
	Don't return an error code; errors are implied by marking the
	file NEVER_REREAD.
	(_cpp_execute_include): Move the recursion and in-macro checks
	here.  Update for stack_include_file not failing.
	* cpplib.c (cpp_push_buffer): Always succeed, since
	_cpp_execute_include performs the recursion check.  Tidy up.
	* cpplib.h (cpp_push_buffer): Update prototype.

Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.87
diff -u -p -r1.87 cppfiles.c
--- cppfiles.c	2000/12/04 07:32:03	1.87
+++ cppfiles.c	2000/12/05 20:46:36
@@ -74,8 +74,8 @@ static struct include_file *find_include
 				PARAMS ((cpp_reader *, const char *,
 					 struct file_name_list *));
 static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
-static int read_include_file	PARAMS ((cpp_reader *, struct include_file *));
-static int stack_include_file	PARAMS ((cpp_reader *, struct include_file *));
+static void read_include_file	PARAMS ((cpp_reader *, struct include_file *));
+static void stack_include_file	PARAMS ((cpp_reader *, struct include_file *));
 static void purge_cache 	PARAMS ((struct include_file *));
 static void destroy_include_file_node	PARAMS ((splay_tree_value));
 static int report_missing_guard		PARAMS ((splay_tree_node, void *));
@@ -204,10 +204,11 @@ open_file (pfile, filename)
   return 0;
 }
 
-/* Place the file referenced by INC into a new buffer on PFILE's stack.
-   Return 1 if successful, 0 if not.  */
+/* Place the file referenced by INC into a new buffer on PFILE's
+   stack.  If there are errors, or the file should not be re-included,
+   a null buffer is pushed.  */
 
-static int
+static void
 stack_include_file (pfile, inc)
      cpp_reader *pfile;
      struct include_file *inc;
@@ -221,46 +222,38 @@ stack_include_file (pfile, inc)
       filename = pfile->buffer->nominal_fname;
       lineno = pfile->buffer->lineno;
     }
-
-  if (pfile->context->prev)
-    cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
 
-  if (DO_NOT_REREAD (inc))
-    return 0;
+  /* Not in cache?  */
+  if (! inc->buffer)
+    read_include_file (pfile, inc);
 
-  if (inc->buffer == NULL)
-    if (read_include_file (pfile, inc) == 0)
-      return 0;
-
+  /* Push a null buffer.  */
   fp = cpp_push_buffer (pfile, NULL, 0);
-  if (fp == 0)
-    return 0;
-
-  /* Initialise controlling macro state.  */
-  pfile->mi_state = MI_OUTSIDE;
-  pfile->mi_cmacro = 0;
-
   fp->inc = inc;
   fp->nominal_fname = inc->name;
   fp->buf = inc->buffer;
-  fp->rlimit = fp->buf + inc->st.st_size;
+  fp->rlimit = fp->buf;
+  if (! DO_NOT_REREAD (inc))
+    fp->rlimit += inc->st.st_size;
   fp->cur = fp->buf;
-  fp->lineno = 0;
   fp->line_base = fp->buf;
+  fp->lineno = 0;		/* For _cpp_do_file_change.  */
+  fp->inc->refcnt++;
 
   /* The ->actual_dir field is only used when ignore_srcdir is not in effect;
      see do_include */
   if (!CPP_OPTION (pfile, ignore_srcdir))
     fp->actual_dir = actual_directory (pfile, inc->name);
 
-  fp->inc->refcnt++;
+  /* Initialise controlling macro state.  */
+  pfile->mi_state = MI_OUTSIDE;
+  pfile->mi_cmacro = 0;
   pfile->include_depth++;
   pfile->input_stack_listing_current = 0;
 
   _cpp_do_file_change (pfile, FC_ENTER, filename, lineno);
 
   fp->lineno = 1;
-  return 1;
 }
 
 /* Read the file referenced by INC into the file cache.
@@ -278,7 +271,7 @@ stack_include_file (pfile, inc)
 
    FIXME: Flush file cache and try again if we run out of memory.  */
 
-static int
+static void
 read_include_file (pfile, inc)
      cpp_reader *pfile;
      struct include_file *inc;
@@ -289,6 +282,9 @@ read_include_file (pfile, inc)
   static int pagesize = -1;
 #endif
 
+  if (DO_NOT_REREAD (inc))
+    return;
+
   if (S_ISREG (inc->st.st_mode))
     {
       /* off_t might have a wider range than ssize_t - in other words,
@@ -373,7 +369,7 @@ read_include_file (pfile, inc)
   close (inc->fd);
   inc->buffer = buf;
   inc->fd = -1;
-  return 1;
+  return;
 
  perror_fail:
   cpp_error_from_errno (pfile, inc->name);
@@ -382,7 +378,7 @@ read_include_file (pfile, inc)
   close (inc->fd);
   inc->fd = -1;
   inc->cmacro = NEVER_REREAD;
-  return 0;
+  return;
 }
 
 static void
@@ -583,6 +579,20 @@ _cpp_execute_include (pfile, header, no_
   struct include_file *inc;
   char *fname;
 
+  /* Help protect #include or similar from recursion.  */
+  if (pfile->buffer_stack_depth >= CPP_STACK_MAX)
+    {
+      cpp_fatal (pfile, "#include nested too deeply");
+      return;
+    }
+
+  /* Check we've tidied up #include before entering the buffer.  */
+  if (pfile->context->prev)
+    {
+      cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
+      return;
+    }
+
   fname = alloca (len + 1);
   memcpy (fname, header->val.str.text, len);
   fname[len] = '\0';
@@ -613,23 +623,22 @@ _cpp_execute_include (pfile, header, no_
       inc->include_count++;
 
       /* Actually process the file.  */
-      if (stack_include_file (pfile, inc))
-	{
-	  if (angle_brackets)
-	    pfile->system_include_depth++;
+      stack_include_file (pfile, inc);
 
-	  if (no_reinclude)
-	    inc->cmacro = NEVER_REREAD;
+      if (angle_brackets)
+	pfile->system_include_depth++;
+      if (no_reinclude)
+	inc->cmacro = NEVER_REREAD;
 
-	  /* Handle -H option.  */
-	  if (CPP_OPTION (pfile, print_include_names))
-	    {
-	      cpp_buffer *fp = CPP_BUFFER (pfile);
-	      while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
-		putc ('.', stderr);
-	      fprintf (stderr, " %s\n", inc->name);
-	    }
+      /* Handle -H option.  */
+      if (CPP_OPTION (pfile, print_include_names))
+	{
+	  cpp_buffer *fp = CPP_BUFFER (pfile);
+	  while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
+	    putc ('.', stderr);
+	  fprintf (stderr, " %s\n", inc->name);
 	}
+
       return;
     }
       
@@ -730,11 +739,8 @@ _cpp_read_file (pfile, fname)
       return 0;
     }
 
-  /* Return success for zero-length files.  */
-  if (DO_NOT_REREAD (f))
-    return 1;
-
-  return stack_include_file (pfile, f);
+  stack_include_file (pfile, f);
+  return 1;
 }
 
 /* Do appropriate cleanup when a file buffer is popped off the input
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.226
diff -u -p -r1.226 cpplib.c
--- cpplib.c	2000/12/04 07:32:03	1.226
+++ cpplib.c	2000/12/05 20:46:56
@@ -1731,42 +1731,34 @@ handle_assertion (pfile, str, type)
   run_directive (pfile, type, str, count, 0);
 }
 
-/* Allocate a new cpp_buffer for PFILE, and push it on the input
-   buffer stack.  If BUFFER != NULL, then use the LENGTH characters in
-   BUFFER as the new input buffer.  Return the new buffer, or NULL on
-   failure.  */
+/* Push a new buffer on the buffer stack.  Buffer can be NULL, but
+   then LEN should be 0.  Returns the new buffer; it doesn't fail.  */
 
 cpp_buffer *
-cpp_push_buffer (pfile, buffer, length)
+cpp_push_buffer (pfile, buffer, len)
      cpp_reader *pfile;
      const U_CHAR *buffer;
-     long length;
+     size_t len;
 {
-  cpp_buffer *buf = CPP_BUFFER (pfile);
-  cpp_buffer *new;
-  if (++pfile->buffer_stack_depth == CPP_STACK_MAX)
-    {
-      cpp_fatal (pfile, "#include nested too deeply");
-      return NULL;
-    }
+  cpp_buffer *new = xobnew (pfile->buffer_ob, cpp_buffer);
 
-  new = xobnew (pfile->buffer_ob, cpp_buffer);
   /* Clears, amongst other things, if_stack and mi_cmacro.  */
   memset (new, 0, sizeof (cpp_buffer));
-
-  pfile->lexer_pos.output_line = 1;
   new->line_base = new->buf = new->cur = buffer;
-  new->rlimit = buffer + length;
-  new->prev = buf;
+  new->rlimit = buffer + len;
+  new->prev = pfile->buffer;
   new->pfile = pfile;
   /* Preprocessed files don't do trigraph and escaped newline processing.  */
   new->from_stage3 = CPP_OPTION (pfile, preprocessed);
   /* No read ahead or extra char initially.  */
   new->read_ahead = EOF;
   new->extra_char = EOF;
+
   pfile->state.next_bol = 1;
+  pfile->buffer_stack_depth++;
+  pfile->lexer_pos.output_line = 1;
 
-  CPP_BUFFER (pfile) = new;
+  pfile->buffer = new;
   return new;
 }
 
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.145
diff -u -p -r1.145 cpplib.h
--- cpplib.h	2000/12/04 07:32:04	1.145
+++ cpplib.h	2000/12/05 20:46:59
@@ -725,7 +725,7 @@ extern void cpp_undef  PARAMS ((cpp_read
 extern void cpp_unassert PARAMS ((cpp_reader *, const char *));
 
 extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
-					    const unsigned char *, long));
+					    const unsigned char *, size_t));
 extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
 extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
 

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