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/sm-taint.cc | |
parent | 5a4e208022e7047af3a15a3dedb715ad801db160 (diff) | |
download | gcc-7fd6e36ea9aa8575841ff1da08b4aebc0298abe2.zip gcc-7fd6e36ea9aa8575841ff1da08b4aebc0298abe2.tar.gz gcc-7fd6e36ea9aa8575841ff1da08b4aebc0298abe2.tar.bz2 |
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/sm-taint.cc')
-rw-r--r-- | gcc/analyzer/sm-taint.cc | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index a13c2fe..e2c78cd 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -180,6 +180,11 @@ public: const char *get_kind () const FINAL OVERRIDE { return "tainted_array_index"; } + int get_controlling_option () const FINAL OVERRIDE + { + return OPT_Wanalyzer_tainted_array_index; + } + bool emit (rich_location *rich_loc) FINAL OVERRIDE { diagnostic_metadata m; @@ -190,19 +195,19 @@ public: default: gcc_unreachable (); case BOUNDS_NONE: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_array_index, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE" " in array lookup without bounds checking", m_arg); break; case BOUNDS_UPPER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_array_index, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE" " in array lookup without checking for negative", m_arg); break; case BOUNDS_LOWER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_array_index, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE" " in array lookup without upper-bounds checking", m_arg); @@ -248,6 +253,11 @@ public: const char *get_kind () const FINAL OVERRIDE { return "tainted_offset"; } + int get_controlling_option () const FINAL OVERRIDE + { + return OPT_Wanalyzer_tainted_offset; + } + bool emit (rich_location *rich_loc) FINAL OVERRIDE { diagnostic_metadata m; @@ -259,19 +269,19 @@ public: default: gcc_unreachable (); case BOUNDS_NONE: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_offset, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as offset" " without bounds checking", m_arg); break; case BOUNDS_UPPER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_offset, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as offset" " without lower-bounds checking", m_arg); break; case BOUNDS_LOWER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_offset, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as offset" " without upper-bounds checking", m_arg); @@ -283,17 +293,17 @@ public: default: gcc_unreachable (); case BOUNDS_NONE: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_offset, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as offset" " without bounds checking"); break; case BOUNDS_UPPER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_offset, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as offset" " without lower-bounds checking"); break; case BOUNDS_LOWER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_offset, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as offset" " without upper-bounds checking"); break; @@ -353,6 +363,11 @@ public: const char *get_kind () const OVERRIDE { return "tainted_size"; } + int get_controlling_option () const FINAL OVERRIDE + { + return OPT_Wanalyzer_tainted_size; + } + bool emit (rich_location *rich_loc) OVERRIDE { diagnostic_metadata m; @@ -362,19 +377,19 @@ public: default: gcc_unreachable (); case BOUNDS_NONE: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as size" " without bounds checking", m_arg); break; case BOUNDS_UPPER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as size" " without lower-bounds checking", m_arg); break; case BOUNDS_LOWER: - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as size" " without upper-bounds checking", m_arg); @@ -455,18 +470,23 @@ public: const char *get_kind () const FINAL OVERRIDE { return "tainted_divisor"; } + int get_controlling_option () const FINAL OVERRIDE + { + return OPT_Wanalyzer_tainted_divisor; + } + bool emit (rich_location *rich_loc) FINAL OVERRIDE { diagnostic_metadata m; /* CWE-369: "Divide By Zero". */ m.add_cwe (369); if (m_arg) - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_divisor, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as divisor" " without checking for zero", m_arg); else - return warning_meta (rich_loc, m, OPT_Wanalyzer_tainted_divisor, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as divisor" " without checking for zero"); } @@ -503,6 +523,11 @@ public: return "tainted_allocation_size"; } + int get_controlling_option () const FINAL OVERRIDE + { + return OPT_Wanalyzer_tainted_allocation_size; + } + bool emit (rich_location *rich_loc) FINAL OVERRIDE { diagnostic_metadata m; @@ -515,22 +540,19 @@ public: default: gcc_unreachable (); case BOUNDS_NONE: - return warning_meta (rich_loc, m, - OPT_Wanalyzer_tainted_allocation_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as" " allocation size without bounds checking", m_arg); break; case BOUNDS_UPPER: - return warning_meta (rich_loc, m, - OPT_Wanalyzer_tainted_allocation_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as" " allocation size without lower-bounds checking", m_arg); break; case BOUNDS_LOWER: - return warning_meta (rich_loc, m, - OPT_Wanalyzer_tainted_allocation_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value %qE as" " allocation size without upper-bounds checking", m_arg); @@ -542,22 +564,19 @@ public: default: gcc_unreachable (); case BOUNDS_NONE: - return warning_meta (rich_loc, m, - OPT_Wanalyzer_tainted_allocation_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as" " allocation size without bounds" " checking"); break; case BOUNDS_UPPER: - return warning_meta (rich_loc, m, - OPT_Wanalyzer_tainted_allocation_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as" " allocation size without lower-bounds" " checking"); break; case BOUNDS_LOWER: - return warning_meta (rich_loc, m, - OPT_Wanalyzer_tainted_allocation_size, + return warning_meta (rich_loc, m, get_controlling_option (), "use of attacker-controlled value as" " allocation size without upper-bounds" " checking"); |