diff options
author | David Malcolm <dmalcolm@redhat.com> | 2019-12-23 20:02:54 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-01-14 21:10:45 -0500 |
commit | 71dcf0c4aaef7d9ac814250018242a6b5dc7705b (patch) | |
tree | bf7fa78e80f27d7bbc65da85d6f3a9b9c2c9c451 /gcc/analyzer/sm-file.cc | |
parent | ab7c7b46c35ed1be68d4c020a2f20ee96f68b64b (diff) | |
download | gcc-71dcf0c4aaef7d9ac814250018242a6b5dc7705b.zip gcc-71dcf0c4aaef7d9ac814250018242a6b5dc7705b.tar.gz gcc-71dcf0c4aaef7d9ac814250018242a6b5dc7705b.tar.bz2 |
diagnostic_path: avoid printing redundant data
This patch tweaks the default implementation of diagnostic_path
printing (-fdiagnostics-path-format=inline-events) to be less verbose
for various common cases.
Consider this synthetic diagnostic from the test plugin:
test.c: In function 'test':
test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which
requires a non-NULL parameter
29 | PyList_Append(list, item);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
'test': events 1-3
|
| 25 | list = PyList_New(0);
| | ^~~~~~~~~~~~~
| | |
| | (1) when 'PyList_New' fails, returning NULL
| 26 |
| 27 | for (i = 0; i < count; i++) {
| | ~~~
| | |
| | (2) when 'i < count'
| 28 | item = PyLong_FromLong(random());
| 29 | PyList_Append(list, item);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
|
The diagnostic's primary location_t is contained within the path, so
printing the source code for it at the top before the path is redundant.
Also, this path is purely intraprocedural, so there's no point in
printing the "interprocedural margin" on the left-hand side, and there's
a single event run, so there's no point in printing the header for the
run.
This patch simplifies the output for the above to:
test.c: In function 'test':
test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which
requires a non-NULL parameter
25 | list = PyList_New(0);
| ^~~~~~~~~~~~~
| |
| (1) when 'PyList_New' fails, returning NULL
26 |
27 | for (i = 0; i < count; i++) {
| ~~~
| |
| (2) when 'i < count'
28 | item = PyLong_FromLong(random());
29 | PyList_Append(list, item);
| ~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| (3) when calling 'PyList_Append', passing NULL from (1) as argument 1
The patch replaces the diagnostic_context's print_path callback with an
object with two vfuncs, allowing for eliding diagnostic_show_locus for
the rich_location in favor of just printing the path for the common case
of a single location_t that's within the path, no fix-it hints or
labels, and -fdiagnostics-path-format=inline-events.
This went through several iterations; in one iteration I attempted to
use a small class hierarchy of per enum diagnostics_output_format
path_printer subclasses; this didn't work because the option-handling
is done in opts.o:common_handle_option, which is in
OBJS-libcommon-target, which isn't "tree-ish". So this version has
a single implementation subclass in tree-diagnostic-path.cc.
This patch contains the non-analyzer changes; a follow-up updates the
expected output for the analyzer testsuite.
gcc/ChangeLog:
* diagnostic-format-json.cc (diagnostic_output_format_init): For
the JSON case, update for conversion from a print_path callback to
a m_path_printer object, deleting any such object.
* diagnostic-show-locus.c (diagnostic_show_locus): Call any
path_printer's maybe_print_path_rather_than_richloc and
potentially bail out early.
* diagnostic.c (diagnostic_initialize): Initializer m_path_printer
and make_json_for_path.
(diagnostic_finish): Delete any m_path_printer.
(diagnostic_show_any_path): Update to call any m_path_printer's
print_path vfunc.
(rich_location::path_makes_location_redundant_p): New function.
* diagnostic.h (class path_printer): New class.
(diagnostic_context::print_path): Replace this callback with...
(diagnostic_context::m_path_printer): ...this object pointer.
(diagnostic_context::make_json_for_path): Fix overlong line.
* doc/invoke.texi (-fdiagnostics-path-format=inline-events):
Update intraprocedural example to reflect removal of event run
header and interprocedural margin. Add sentence describing
how source code for location can be elided.
(-fdiagnostics-show-path-depths): Fix reference to pertinent
option.
* tree-diagnostic-path.cc: (path_summary::m_path): New field.
(path_summary::path_summary): Initialize it.
(print_fndecl): Likewise.
(path_summary::print): Add param "need_event_header". Determine
if the path is interprocedural vs purely intraprocedural. Only
print headers for event-runs if we need to, or if there's more
than one event-run. Only print the "interprocedural border" for
interprocedural paths. Only print the function name in event-run
headers for interprocedural paths.
(default_tree_diagnostic_path_printer): Replace with...
(class impl_path_printer): ...this class.
(path_printer::make_tree_default): New function.
(selftest::test_intraprocedural_path): Update expected result for
above changes; do with and without requiring event headers.
* tree-diagnostic.c (tree_diagnostics_defaults): Replace
initialization of print_path with that for m_path_printer.
* tree-diagnostic.h (default_tree_diagnostic_path_printer): Delete decl.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic-path-format-default.c: Update expected
output to remove source code from diagnostic locus, made redundant
by path.
* gcc.dg/plugin/diagnostic-path-format-inline-events-1.c:
Likewise.
* gcc.dg/plugin/diagnostic-path-format-inline-events-2.c:
Likewise.
* gcc.dg/plugin/diagnostic-path-format-inline-events-3.c:
Likewise.
* gcc.dg/plugin/diagnostic-test-paths-2.c: Likewise; also
remove redundant event run header and interprocedual margin.
* gcc.dg/plugin/diagnostic-test-paths-2a.c: New test.
* gcc.dg/plugin/diagnostic-test-paths-4.c: Update expected output
to remove source code from diagnostic locus, made redundant by
path.
* gcc.dg/plugin/diagnostic_plugin_test_paths.c
(class pass_test_show_path): Add an m_dummy_label field and
initialize it in the ctor.
(example_1): Add a "dummy_label" param. Use it to optionally add
a labelled to the rich_location.
(pass_test_show_path::execute): Pass m_dummy_label to the call to
example_1.
(make_pass_test_show_path): Delete.
(plugin_init): Look for a "dummy_label" plugin argument and use
it to initialize the pass's m_dummy_label field. Call new directly
to avoid passing around such params.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add new test.
libcpp/ChangeLog:
* include/line-map.h
(rich_location::path_makes_location_redundant_p): New decl.
Diffstat (limited to 'gcc/analyzer/sm-file.cc')
0 files changed, 0 insertions, 0 deletions