diff options
author | David Malcolm <dmalcolm@redhat.com> | 2022-03-16 10:54:44 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2022-03-16 14:01:19 -0400 |
commit | 7fd6e36ea9aa8575841ff1da08b4aebc0298abe2 (patch) | |
tree | 311949c4814ad5d9639fc8c5158e683bf817b3e3 /gcc/analyzer/diagnostic-manager.cc | |
parent | 5a4e208022e7047af3a15a3dedb715ad801db160 (diff) |
analyzer: early rejection of disabled warnings [PR104955]
Avoid generating execution paths for warnings that are ultimately
rejected due to -Wno-analyzer-* flags.
This improves the test case from taking at least several minutes
(before I killed it) to taking under a second.
This doesn't fix the slowdown seen in PR analyzer/104955 with large
numbers of warnings when the warnings are still enabled.
gcc/analyzer/ChangeLog:
PR analyzer/104955
* diagnostic-manager.cc (get_emission_location): New.
(diagnostic_manager::diagnostic_manager): Initialize
m_num_disabled_diagnostics.
(diagnostic_manager::add_diagnostic): Reject diagnostics that
will eventually be rejected due to being disabled.
(diagnostic_manager::emit_saved_diagnostics): Log the number
of disabled diagnostics.
(diagnostic_manager::emit_saved_diagnostic): Split out logic for
determining emission location to get_emission_location.
* diagnostic-manager.h
(diagnostic_manager::m_num_disabled_diagnostics): New field.
* engine.cc (stale_jmp_buf::get_controlling_option): New.
(stale_jmp_buf::emit): Use it.
* pending-diagnostic.h
(pending_diagnostic::get_controlling_option): New vfunc.
* region-model.cc
(poisoned_value_diagnostic::get_controlling_option): New.
(poisoned_value_diagnostic::emit): Use it.
(shift_count_negative_diagnostic::get_controlling_option): New.
(shift_count_negative_diagnostic::emit): Use it.
(shift_count_overflow_diagnostic::get_controlling_option): New.
(shift_count_overflow_diagnostic::emit): Use it.
(dump_path_diagnostic::get_controlling_option): New.
(dump_path_diagnostic::emit): Use it.
(write_to_const_diagnostic::get_controlling_option): New.
(write_to_const_diagnostic::emit): Use it.
(write_to_string_literal_diagnostic::get_controlling_option): New.
(write_to_string_literal_diagnostic::emit): Use it.
* sm-file.cc (double_fclose::get_controlling_option): New.
(double_fclose::emit): Use it.
(file_leak::get_controlling_option): New.
(file_leak::emit): Use it.
* sm-malloc.cc (mismatching_deallocation::get_controlling_option):
New.
(mismatching_deallocation::emit): Use it.
(double_free::get_controlling_option): New.
(double_free::emit): Use it.
(possible_null_deref::get_controlling_option): New.
(possible_null_deref::emit): Use it.
(possible_null_arg::get_controlling_option): New.
(possible_null_arg::emit): Use it.
(null_deref::get_controlling_option): New.
(null_deref::emit): Use it.
(null_arg::get_controlling_option): New.
(null_arg::emit): Use it.
(use_after_free::get_controlling_option): New.
(use_after_free::emit): Use it.
(malloc_leak::get_controlling_option): New.
(malloc_leak::emit): Use it.
(free_of_non_heap::get_controlling_option): New.
(free_of_non_heap::emit): Use it.
* sm-pattern-test.cc (pattern_match::get_controlling_option): New.
(pattern_match::emit): Use it.
* sm-sensitive.cc
(exposure_through_output_file::get_controlling_option): New.
(exposure_through_output_file::emit): Use it.
* sm-signal.cc (signal_unsafe_call::get_controlling_option): New.
(signal_unsafe_call::emit): Use it.
* sm-taint.cc (tainted_array_index::get_controlling_option): New.
(tainted_array_index::emit): Use it.
(tainted_offset::get_controlling_option): New.
(tainted_offset::emit): Use it.
(tainted_size::get_controlling_option): New.
(tainted_size::emit): Use it.
(tainted_divisor::get_controlling_option): New.
(tainted_divisor::emit): Use it.
(tainted_allocation_size::get_controlling_option): New.
(tainted_allocation_size::emit): Use it.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/many-disabled-diagnostics.c: New test.
* gcc.dg/plugin/analyzer_gil_plugin.c
(gil_diagnostic::get_controlling_option): New.
(double_save_thread::emit): Use it.
(fncall_without_gil::emit): Likewise.
(pyobject_usage_without_gil::emit): Likewise.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/diagnostic-manager.cc')
-rw-r--r-- | gcc/analyzer/diagnostic-manager.cc | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 561bb18cee0..d5e5b6926cc 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -849,13 +849,28 @@ private: const feasibility_problem *m_feasibility_problem; }; +/* Determine the emission location for PD at STMT in FUN. */ + +static location_t +get_emission_location (const gimple *stmt, function *fun, + const pending_diagnostic &pd) +{ + location_t loc = get_stmt_location (stmt, fun); + + /* Allow the pending_diagnostic to fix up the location. */ + loc = pd.fixup_location (loc); + + return loc; +} + /* class diagnostic_manager. */ /* diagnostic_manager's ctor. */ diagnostic_manager::diagnostic_manager (logger *logger, engine *eng, int verbosity) -: log_user (logger), m_eng (eng), m_verbosity (verbosity) +: log_user (logger), m_eng (eng), m_verbosity (verbosity), + m_num_disabled_diagnostics (0) { } @@ -877,6 +892,25 @@ diagnostic_manager::add_diagnostic (const state_machine *sm, through the exploded_graph to the diagnostic. */ gcc_assert (enode); + /* If this warning is ultimately going to be rejected by a -Wno-analyzer-* + flag, reject it now. + We can only do this for diagnostics where we already know the stmt, + and thus can determine the emission location. */ + if (stmt) + { + location_t loc = get_emission_location (stmt, snode->m_fun, *d); + int option = d->get_controlling_option (); + if (!warning_enabled_at (loc, option)) + { + if (get_logger ()) + get_logger ()->log ("rejecting disabled warning %qs", + d->get_kind ()); + delete d; + m_num_disabled_diagnostics++; + return; + } + } + saved_diagnostic *sd = new saved_diagnostic (sm, enode, snode, stmt, finder, var, sval, state, d, m_saved_diagnostics.length ()); @@ -1186,6 +1220,7 @@ diagnostic_manager::emit_saved_diagnostics (const exploded_graph &eg) LOG_SCOPE (get_logger ()); auto_timevar tv (TV_ANALYZER_DIAGNOSTICS); log ("# saved diagnostics: %i", m_saved_diagnostics.length ()); + log ("# disabled diagnostics: %i", m_num_disabled_diagnostics); if (get_logger ()) { unsigned i; @@ -1265,11 +1300,10 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg, emission_path.prepare_for_emission (sd.m_d); - location_t loc = get_stmt_location (sd.m_stmt, sd.m_snode->m_fun); + location_t loc + = get_emission_location (sd.m_stmt, sd.m_snode->m_fun, *sd.m_d); - /* Allow the pending_diagnostic to fix up the primary location - and any locations for events. */ - loc = sd.m_d->fixup_location (loc); + /* Allow the pending_diagnostic to fix up the locations of events. */ emission_path.fixup_locations (sd.m_d); gcc_rich_location rich_loc (loc); |