re PR preprocessor/15167 (Internal compiler error with "#pragma once")
authorEric Botcazou <ebotcazou@libertysurf.fr>
Wed, 15 Dec 2004 13:31:28 +0000 (14:31 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 15 Dec 2004 13:31:28 +0000 (13:31 +0000)
PR preprocessor/15167
* files.c (destroy_cpp_file): New function.
(should_stack_file): Make a new file if the
compared file is still stacked.

From-SVN: r92194

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/inc/pragma-once-1a.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/pragma-once-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/pragma-once-1b.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/pragma-once-1c.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/pragma-once-1d.h [new file with mode: 0644]
libcpp/ChangeLog
libcpp/files.c

index c5ba7ed..80fb3cc 100644 (file)
@@ -1,3 +1,11 @@
+2004-12-15  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * cpp/pragma-once-1.c: New test.
+       * cpp/pragma-once-1b.h: Likewise.
+       * cpp/pragma-once-1c.h: Likewise.
+       * cpp/pragma-once-1d.h: Likewise.
+       * cpp/inc/pragma-once-1a.h: Likewise.
+
 2004-12-15  Bud Davis  <bdavis9659@comcast.net>
             Steven G. Kargle  <kargls@comcast.net>
 
diff --git a/gcc/testsuite/gcc.dg/cpp/inc/pragma-once-1a.h b/gcc/testsuite/gcc.dg/cpp/inc/pragma-once-1a.h
new file mode 100644 (file)
index 0000000..7de6412
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _A_H_
+#define _A_H_
+
+#include "../pragma-once-1b.h"
+
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/pragma-once-1.c b/gcc/testsuite/gcc.dg/cpp/pragma-once-1.c
new file mode 100644 (file)
index 0000000..23e24b8
--- /dev/null
@@ -0,0 +1,8 @@
+/* PR preprocessor/15167 */
+/* Origin: Roland Meub <Roland.Meub@Tenovis.com> */
+
+/* { dg-do compile } */
+/* { dg-options "-I." } */
+
+#include "inc/pragma-once-1a.h"
+#include "pragma-once-1d.h"
diff --git a/gcc/testsuite/gcc.dg/cpp/pragma-once-1b.h b/gcc/testsuite/gcc.dg/cpp/pragma-once-1b.h
new file mode 100644 (file)
index 0000000..9c17db4
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _B_H_
+#define _B_H_
+
+#pragma once
+
+#include "pragma-once-1c.h"
+
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/pragma-once-1c.h b/gcc/testsuite/gcc.dg/cpp/pragma-once-1c.h
new file mode 100644 (file)
index 0000000..cd50024
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _C_H_
+#define _C_H_
+
+#include "pragma-once-1b.h"
+
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/pragma-once-1d.h b/gcc/testsuite/gcc.dg/cpp/pragma-once-1d.h
new file mode 100644 (file)
index 0000000..0c5db2d
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _D_H_
+#define _D_H_
+
+#include "pragma-once-1b.h"
+
+#endif
index 3b01f82..41e8aae 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-15  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR preprocessor/15167
+       * files.c (destroy_cpp_file): New function.
+       (should_stack_file): Make a new file if the
+       compared file is still stacked.
+
 2004-11-28  Nathanael Nerode  <neroden@gcc.gnu.org>
 
        PR preprocessor/17610 
index fc1fa2c..bd5f8dd 100644 (file)
@@ -161,6 +161,7 @@ static void open_file_failed (cpp_reader *pfile, _cpp_file *file);
 static struct file_hash_entry *search_cache (struct file_hash_entry *head,
                                             const cpp_dir *start_dir);
 static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
+static void destroy_cpp_file (_cpp_file *);
 static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
 static void allocate_file_hash_entries (cpp_reader *pfile);
 static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
@@ -667,12 +668,38 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
       if ((import || f->once_only)
          && f->err_no == 0
          && f->st.st_mtime == file->st.st_mtime
-         && f->st.st_size == file->st.st_size
-         && read_file (pfile, f)
-         /* Size might have changed in read_file().  */
-         && f->st.st_size == file->st.st_size
-         && !memcmp (f->buffer, file->buffer, f->st.st_size))
-       break;
+         && f->st.st_size == file->st.st_size)
+       {
+         _cpp_file *ref_file;
+         bool same_file_p = false;
+
+         if (f->buffer && !f->buffer_valid)
+           {
+             /* We already have a buffer but it is not valid, because
+                the file is still stacked.  Make a new one.  */
+             ref_file = make_cpp_file (pfile, f->dir, f->name);
+             ref_file->path = f->path;
+           }
+         else
+           /* The file is not stacked anymore.  We can reuse it.  */
+           ref_file = f;
+
+         same_file_p = read_file (pfile, ref_file)
+                       /* Size might have changed in read_file().  */
+                       && ref_file->st.st_size == file->st.st_size
+                       && !memcmp (ref_file->buffer,
+                                   file->buffer,
+                                   file->st.st_size);
+
+         if (f->buffer && !f->buffer_valid)
+           {
+             ref_file->path = 0;
+             destroy_cpp_file (ref_file);
+           }
+
+         if (same_file_p)
+           break;
+       }
     }
 
   return f == NULL;
@@ -870,6 +897,16 @@ make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname)
   return file;
 }
 
+/* Release a _cpp_file structure.  */
+static void
+destroy_cpp_file (_cpp_file *file)
+{
+  if (file->buffer)
+    free ((void *) file->buffer);
+  free ((void *) file->name);
+  free (file);
+}
+
 /* A hash of directory names.  The directory names are the path names
    of files which contain a #include "", the included file name is
    appended to this directories.