Evict selftest tempfiles from the diagnostics file cache
authorDavid Malcolm <dmalcolm@redhat.com>
Thu, 18 Aug 2016 13:07:53 +0000 (13:07 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Thu, 18 Aug 2016 13:07:53 +0000 (13:07 +0000)
Selftests can use class selftest::temp_source_file to write out files
for testing input-handling, and the files are unlinked in the dtor.

This leads to stale entries in input.c's cache of file content, which
could lead to errors if a temporary filename gets reused during a run
of the selftests.

We don't normally expect files to be "deleted from under us", so
special-case this by adding a special way for temp_source_file's
dtor to purge any cache entries referring to it.

gcc/ChangeLog:
* input.c (diagnostics_file_cache_forcibly_evict_file): New
function.
* input.h (diagnostics_file_cache_forcibly_evict_file): New
declaration.
* selftest.c (selftest::temp_source_file::~temp_source_file):
Evict m_filename from the diagnostic file cache.

From-SVN: r239570

gcc/ChangeLog
gcc/input.c
gcc/input.h
gcc/selftest.c

index 7df2a9a5c50d7218cac1e268f381af9f49f69de0..eb870117a3c13c10bec5cb49d233889381b74a62 100644 (file)
@@ -1,3 +1,12 @@
+2016-08-18  David Malcolm  <dmalcolm@redhat.com>
+
+       * input.c (diagnostics_file_cache_forcibly_evict_file): New
+       function.
+       * input.h (diagnostics_file_cache_forcibly_evict_file): New
+       declaration.
+       * selftest.c (selftest::temp_source_file::~temp_source_file):
+       Evict m_filename from the diagnostic file cache.
+
 2016-08-18  Richard Biener  <rguenther@suse.de>
 
        * tree-pass.h (make_pass_materialize_all_clones): Declare.
index 172d13a8ad7dd7c449c96727dc3cdd0c77af2687..76a33077bc29e70ae8675dd83203a2c291e9360c 100644 (file)
@@ -249,6 +249,32 @@ lookup_file_in_cache_tab (const char *file_path)
   return r;
 }
 
+/* Purge any mention of FILENAME from the cache of files used for
+   printing source code.  For use in selftests when working
+   with tempfiles.  */
+
+void
+diagnostics_file_cache_forcibly_evict_file (const char *file_path)
+{
+  gcc_assert (file_path);
+
+  fcache *r = lookup_file_in_cache_tab (file_path);
+  if (!r)
+    /* Not found.  */
+    return;
+
+  r->file_path = NULL;
+  if (r->fp)
+    fclose (r->fp);
+  r->fp = NULL;
+  r->nb_read = 0;
+  r->line_start_idx = 0;
+  r->line_num = 0;
+  r->line_record.truncate (0);
+  r->use_count = 0;
+  r->total_lines = 0;
+}
+
 /* Return the file cache that has been less used, recently, or the
    first empty one.  If HIGHEST_USE_COUNT is non-null,
    *HIGHEST_USE_COUNT is set to the highest use count of the entries
index c17e440e576fc6ab90900b492cdf5823ed223763..0f187c7f2ba8765f335f153a04ff674773d351c5 100644 (file)
@@ -95,6 +95,8 @@ void dump_location_info (FILE *stream);
 
 void diagnostics_file_cache_fini (void);
 
+void diagnostics_file_cache_forcibly_evict_file (const char *file_path);
+
 struct GTY(()) string_concat
 {
   string_concat (int num, location_t *locs);
index 0a7192efe460b41c6de30c8096e803093eca8432..d25f5c08db7e782b2385c363809ad3bbd7755bd7 100644 (file)
@@ -111,6 +111,7 @@ selftest::temp_source_file::temp_source_file (const location &loc,
 selftest::temp_source_file::~temp_source_file ()
 {
   unlink (m_filename);
+  diagnostics_file_cache_forcibly_evict_file (m_filename);
   free (m_filename);
 }