summaryrefslogtreecommitdiff
path: root/gcc/analyzer/diagnostic-manager.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-03-16 10:54:44 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2022-03-16 14:01:19 -0400
commit7fd6e36ea9aa8575841ff1da08b4aebc0298abe2 (patch)
tree311949c4814ad5d9639fc8c5158e683bf817b3e3 /gcc/analyzer/diagnostic-manager.cc
parent5a4e208022e7047af3a15a3dedb715ad801db160 (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.cc44
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);