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] Fix pch failures when opening a header that has been precompiled multiple times (PR pch/13675)


Hi!

When a header file is included multiple times and has been precompiled,
gcc fails with error: calling fdopen: Bad file descriptor.
The problem is that file->fd is closed after cb.read_pch and set to -1,
so the next time should_stack_file is called on it, c_common_read_pch
which starts with fdopen (fd, "rb"); really has to fail.
The fix below clears pch (and frees pchname) once the *.gch file
is read using cb.read_pch, which means that an include file won't be
handled as a PCH file in the second and following #include (which matches
the PCH design).

This patch also removes unnecessary field from struct _cpp_file (file->pch
is true iff file->pchname != NULL) and fixes a double close bug -
FILE *f = fdopen (fd, "rb");
if (f)
  fclose (f);
already closes the fd if f wasn't NULL, so it shouldn't be closed again
by the caller.

No testcase, as the testcase doesn't fit into the dg-pch.exp machinery
which insists a header is only used from *.gch.

Ok for trunk?

2008-03-31  Jakub Jelinek  <jakub@redhat.com>

	PR pch/13675
	* files.c (struct _cpp_file): Remove pch field.
	(pch_open_file): Don't set file->pch, just file->pchname.
	(should_stack_file): After pfile->cb.read_pch call
	free pchname and clear pchname, don't close file->fd.
	Test file->pchname instead of file->pch.  Don't close fd after cb.
	(_cpp_stack_include): Test file->pchname instead of file->pch.

	* c-pch.c (c_common_read_pch): On error close (fd) resp. fclose (f).

--- libcpp/files.c.jj	2008-02-18 23:50:17.000000000 +0100
+++ libcpp/files.c	2008-03-31 15:59:01.000000000 +0200
@@ -1,6 +1,6 @@
 /* Part of CPP library.  File handling.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
@@ -106,9 +106,6 @@ struct _cpp_file
 
   /* If BUFFER above contains the true contents of the file.  */
   bool buffer_valid;
-
-  /* File is a PCH (on return from find_include_file).  */
-  bool pch;
 };
 
 /* A singly-linked list for all searches for a given file name, with
@@ -322,9 +319,7 @@ pch_open_file (cpp_reader *pfile, _cpp_f
 	    }
 	  closedir (pchdir);
 	}
-      if (valid)
-	file->pch = true;
-      else
+      if (!valid)
 	*invalid_pch = true;
     }
 
@@ -703,11 +698,12 @@ should_stack_file (cpp_reader *pfile, _c
     return false;
 
   /* Handle PCH files immediately; don't stack them.  */
-  if (file->pch)
+  if (file->pchname)
     {
       pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path);
-      close (file->fd);
       file->fd = -1;
+      free ((void *) file->pchname);
+      file->pchname = NULL;
       return false;
     }
 
@@ -916,7 +912,7 @@ _cpp_stack_include (cpp_reader *pfile, c
      complicates LAST_SOURCE_LINE_LOCATION.  This does not apply if we
      found a PCH file (in which case linemap_add is not called) or we
      were included from the command-line.  */
-  if (! file->pch && file->err_no == 0 && type != IT_CMDLINE)
+  if (file->pchname == NULL && file->err_no == 0 && type != IT_CMDLINE)
     pfile->line_table->highest_location--;
 
   return _cpp_stack_file (pfile, file, type == IT_IMPORT);
--- gcc/c-pch.c.jj	2008-02-18 23:46:08.000000000 +0100
+++ gcc/c-pch.c	2008-03-31 15:56:00.000000000 +0200
@@ -372,6 +372,7 @@ c_common_read_pch (cpp_reader *pfile, co
   if (f == NULL)
     {
       cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
+      close (fd);
       return;
     }
 
@@ -380,6 +381,7 @@ c_common_read_pch (cpp_reader *pfile, co
   if (fread (&h, sizeof (h), 1, f) != 1)
     {
       cpp_errno (pfile, CPP_DL_ERROR, "reading");
+      fclose (f);
       return;
     }
 
@@ -425,7 +427,10 @@ c_common_read_pch (cpp_reader *pfile, co
   gt_pch_restore (f);
 
   if (cpp_read_state (pfile, name, f, smd) != 0)
-    return;
+    {
+      fclose (f);
+      return;
+    }
 
   fclose (f);
 

	Jakub


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