diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-08-02 20:07:28 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-08-02 20:07:28 +0000 |
commit | 653fee1961981f1fee3a0ced7ac4d36b4cec2064 (patch) | |
tree | d0ee6f17465a7f19034bba6642c775e21173d97b /gcc/pretty-print.c | |
parent | 74f9986eafd45489ff6563d6bb824ec1ad39cd14 (diff) | |
download | gcc-653fee1961981f1fee3a0ced7ac4d36b4cec2064.zip gcc-653fee1961981f1fee3a0ced7ac4d36b4cec2064.tar.gz gcc-653fee1961981f1fee3a0ced7ac4d36b4cec2064.tar.bz2 |
Fix memory leak of pretty_printer prefixes
We were rather sloppy about handling the ownership of prefixes for
pretty_printer, and this lead to a memory leak for any time a
diagnostic_show_locus call emits multiple line spans.
This showed up in "make selftest-valgrind" as:
3,976 bytes in 28 blocks are definitely lost in loss record 632 of 669
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x1F08227: xmalloc (xmalloc.c:147)
by 0x1F083E6: xvasprintf (xvasprintf.c:58)
by 0x1E7EC7D: build_message_string(char const*, ...) (diagnostic.c:78)
by 0x1E7F438: diagnostic_get_location_text(diagnostic_context*, expanded_location) (diagnostic.c:328)
by 0x1E7FD54: default_diagnostic_start_span_fn(diagnostic_context*, expanded_location) (diagnostic.c:626)
by 0x1EB3508: selftest::test_diagnostic_context::start_span_cb(diagnostic_context*, expanded_location) (selftest-diagnostic.c:57)
by 0x1E89215: diagnostic_show_locus(diagnostic_context*, rich_location*, diagnostic_t) (diagnostic-show-locus.c:1992)
by 0x1E8ECAD: selftest::test_fixit_insert_containing_newline_2(selftest::line_table_case const&) (diagnostic-show-locus.c:3044)
by 0x1EB0606: selftest::for_each_line_table_case(void (*)(selftest::line_table_case const&)) (input.c:3525)
by 0x1E8F3F5: selftest::diagnostic_show_locus_c_tests() (diagnostic-show-locus.c:3164)
by 0x1E010BF: selftest::run_tests() (selftest-run-tests.c:88)
4,004 bytes in 28 blocks are definitely lost in loss record 633 of 669
at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x1F08227: xmalloc (xmalloc.c:147)
by 0x1F083E6: xvasprintf (xvasprintf.c:58)
by 0x1E7EC7D: build_message_string(char const*, ...) (diagnostic.c:78)
by 0x1E7F438: diagnostic_get_location_text(diagnostic_context*, expanded_location) (diagnostic.c:328)
by 0x1E7FD54: default_diagnostic_start_span_fn(diagnostic_context*, expanded_location) (diagnostic.c:626)
by 0x1EB3508: selftest::test_diagnostic_context::start_span_cb(diagnostic_context*, expanded_location) (selftest-diagnostic.c:57)
by 0x1E89215: diagnostic_show_locus(diagnostic_context*, rich_location*, diagnostic_t) (diagnostic-show-locus.c:1992)
by 0x1E8B373: selftest::test_diagnostic_show_locus_fixit_lines(selftest::line_table_case const&) (diagnostic-show-locus.c:2500)
by 0x1EB0606: selftest::for_each_line_table_case(void (*)(selftest::line_table_case const&)) (input.c:3525)
by 0x1E8F3B9: selftest::diagnostic_show_locus_c_tests() (diagnostic-show-locus.c:3159)
by 0x1E010BF: selftest::run_tests() (selftest-run-tests.c:88)
This patch fixes the leaks by ensuring that the pretty_printer "owns"
the prefix if it's non-NULL, freeing it in the dtor and in pp_set_prefix.
gcc/cp/ChangeLog:
* error.c (cxx_print_error_function): Duplicate "file" before
passing it to pp_set_prefix.
(cp_print_error_function): Use pp_take_prefix when saving the
existing prefix.
gcc/ChangeLog:
* diagnostic-show-locus.c (diagnostic_show_locus): Use
pp_take_prefix when saving the existing prefix.
* diagnostic.c (diagnostic_append_note): Likewise.
* langhooks.c (lhd_print_error_function): Likewise.
* pretty-print.c (pp_set_prefix): Drop the "const" from "prefix"
param's type. Free the existing prefix.
(pp_take_prefix): New function.
(pretty_printer::pretty_printer): Drop the prefix parameter.
Rename the length parameter to match the comment.
(pretty_printer::~pretty_printer): Free the prefix.
* pretty-print.h (pretty_printer::pretty_printer): Drop the prefix
parameter.
(struct pretty_printer): Drop the "const" from "prefix" field's
type and clarify memory management.
(pp_set_prefix): Drop the "const" from the 2nd param.
(pp_take_prefix): New decl.
From-SVN: r263275
Diffstat (limited to 'gcc/pretty-print.c')
-rw-r--r-- | gcc/pretty-print.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c index dc7791a..736af8f 100644 --- a/gcc/pretty-print.c +++ b/gcc/pretty-print.c @@ -1482,23 +1482,38 @@ pp_clear_output_area (pretty_printer *pp) pp_buffer (pp)->line_length = 0; } -/* Set PREFIX for PRETTY-PRINTER. */ +/* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which + will eventually be free-ed. */ + void -pp_set_prefix (pretty_printer *pp, const char *prefix) +pp_set_prefix (pretty_printer *pp, char *prefix) { + free (pp->prefix); pp->prefix = prefix; pp_set_real_maximum_length (pp); pp->emitted_prefix = false; pp_indentation (pp) = 0; } +/* Take ownership of PP's prefix, setting it to NULL. + This allows clients to save, overide, and then restore an existing + prefix, without it being free-ed. */ + +char * +pp_take_prefix (pretty_printer *pp) +{ + char *result = pp->prefix; + pp->prefix = NULL; + return result; +} + /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */ void pp_destroy_prefix (pretty_printer *pp) { if (pp->prefix != NULL) { - free (CONST_CAST (char *, pp->prefix)); + free (pp->prefix); pp->prefix = NULL; } } @@ -1535,10 +1550,9 @@ pp_emit_prefix (pretty_printer *pp) } } -/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH - characters per line. */ +/* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */ -pretty_printer::pretty_printer (const char *p, int l) +pretty_printer::pretty_printer (int maximum_length) : buffer (new (XCNEW (output_buffer)) output_buffer ()), prefix (), padding (pp_none), @@ -1552,10 +1566,10 @@ pretty_printer::pretty_printer (const char *p, int l) translate_identifiers (true), show_color () { - pp_line_cutoff (this) = l; + pp_line_cutoff (this) = maximum_length; /* By default, we emit prefixes once per message. */ pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE; - pp_set_prefix (this, p); + pp_set_prefix (this, NULL); } pretty_printer::~pretty_printer () @@ -1564,6 +1578,7 @@ pretty_printer::~pretty_printer () delete m_format_postprocessor; buffer->~output_buffer (); XDELETE (buffer); + free (prefix); } /* Append a string delimited by START and END to the output area of |