summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-25 19:24:01 +0000
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-25 19:24:01 +0000
commitc6a7d9e9220dbe338066d0c67e119c8ef2eb442b (patch)
tree577d6785b1d140e60c6a5523ac860ed50ec2e5e3 /libcpp
parentd756621f369969cc5a9d3bec764aec6c5b2a1689 (diff)
input.c/libcpp: fix lifetimes of path buffers
Running "make selftest-valgrind" showed various leaks of the form: 408 bytes in 24 blocks are definitely lost in loss record 572 of 679 at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x1B0D057: xmalloc (xmalloc.c:148) by 0x1ACCAA1: append_file_to_dir(char const*, cpp_dir*) [clone .isra.3] (files.c:1567) by 0x1ACD56F: _cpp_find_file (files.c:390) by 0x1ACF8FB: cpp_read_main_file(cpp_reader*, char const*) (init.c:632) by 0x1AB3D97: selftest::lexer_test::lexer_test(selftest::line_table_case const&, char const*, selftest::lexer_test_options*) (input.c:2014) by 0x1AB792B: selftest::test_lexer_string_locations_u8(selftest::line_table_case const&) (input.c:2713) by 0x1ABA22A: selftest::for_each_line_table_case(void (*)(selftest::line_table_case const&)) (input.c:3227) by 0x1ABA381: selftest::input_c_tests() (input.c:3260) by 0x1A295F1: selftest::run_tests() (selftest-run-tests.c:62) by 0xF20DC4: toplev::run_self_tests() (toplev.c:2076) by 0xF20FCD: toplev::main(int, char**) (toplev.c:2153) Fix the leak by freeing the file->path in destroy_cpp_file. However, doing so would lead to a use-after-free in input.c's file cache since the filenames in this cache are the libcpp file->path buffers. Hence we need to ensure that any references to the file in the input.c cache are purged before cleaning up file->path. This is normally done by the temp_source_file dtor. Hence we need to reorder things to that the temp_source_file dtor runs before cleaning up the cpp_parser. The patch does this by introducing a wrapper class around cpp_parser *, so that the dtor can run after the dtor for temp_source_file. gcc/ChangeLog: * input.c (fcache::file_patch): Add comment about lifetime. (selftest::cpp_reader_ptr): New class. (selftest::lexer_test): Convert m_parser from cpp_reader * to a cpp_reader_ptr, and move m_tempfile to after it. (selftest::lexer_test::lexer_test): Update for above reordering. (lexer_test::~lexer_test): Move cleanup of m_parser to cpp_reader_ptr's dtor. libcpp/ChangeLog: * files.c (destroy_cpp_file): Free file->path. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241536 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog4
-rw-r--r--libcpp/files.c1
2 files changed, 5 insertions, 0 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 5ff0aad08f87..9083bdab980d 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,5 +1,9 @@
2016-10-25 David Malcolm <dmalcolm@redhat.com>
+ * files.c (destroy_cpp_file): Free file->path.
+
+2016-10-25 David Malcolm <dmalcolm@redhat.com>
+
* include/line-map.h (line_maps::~line_maps): New dtor.
(location_adhoc_data_fini): Delete decl.
* line-map.c (line_maps::~line_maps): New dtor.
diff --git a/libcpp/files.c b/libcpp/files.c
index e859dfe36938..2c50e6c27e1b 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -1132,6 +1132,7 @@ destroy_cpp_file (_cpp_file *file)
{
free ((void *) file->buffer_start);
free ((void *) file->name);
+ free ((void *) file->path);
free (file);
}