aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/sm-malloc.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/sm-malloc.cc
parent5a4e208022e7047af3a15a3dedb715ad801db160 (diff)
downloadgcc-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-malloc.cc')
-rw-r--r--gcc/analyzer/sm-malloc.cc72
1 files changed, 57 insertions, 15 deletions
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index a5fa60d..4c03080 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -760,6 +760,11 @@ public:
return "mismatching_deallocation";
}
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_mismatching_deallocation;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
auto_diagnostic_group d;
@@ -767,13 +772,13 @@ public:
m.add_cwe (762); /* CWE-762: Mismatched Memory Management Routines. */
if (const deallocator *expected_dealloc
= m_expected_deallocators->maybe_get_single ())
- return warning_meta (rich_loc, m, OPT_Wanalyzer_mismatching_deallocation,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"%qE should have been deallocated with %qs"
" but was deallocated with %qs",
m_arg, expected_dealloc->m_name,
m_actual_dealloc->m_name);
else
- return warning_meta (rich_loc, m, OPT_Wanalyzer_mismatching_deallocation,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"%qs called on %qE returned from a mismatched"
" allocation function",
m_actual_dealloc->m_name, m_arg);
@@ -834,12 +839,17 @@ public:
const char *get_kind () const FINAL OVERRIDE { return "double_free"; }
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_double_free;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
auto_diagnostic_group d;
diagnostic_metadata m;
m.add_cwe (415); /* CWE-415: Double Free. */
- return warning_meta (rich_loc, m, OPT_Wanalyzer_double_free,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"double-%qs of %qE", m_funcname, m_arg);
}
@@ -925,13 +935,17 @@ public:
const char *get_kind () const FINAL OVERRIDE { return "possible_null_deref"; }
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_possible_null_dereference;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
/* CWE-690: Unchecked Return Value to NULL Pointer Dereference. */
diagnostic_metadata m;
m.add_cwe (690);
- return warning_meta (rich_loc, m,
- OPT_Wanalyzer_possible_null_dereference,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"dereference of possibly-NULL %qE", m_arg);
}
@@ -1010,6 +1024,10 @@ public:
&& m_arg_idx == sub_other.m_arg_idx);
}
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_possible_null_argument;
+ }
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
@@ -1018,7 +1036,7 @@ public:
diagnostic_metadata m;
m.add_cwe (690);
bool warned
- = warning_meta (rich_loc, m, OPT_Wanalyzer_possible_null_argument,
+ = warning_meta (rich_loc, m, get_controlling_option (),
"use of possibly-NULL %qE where non-null expected",
m_arg);
if (warned)
@@ -1058,13 +1076,17 @@ public:
const char *get_kind () const FINAL OVERRIDE { return "null_deref"; }
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_null_dereference;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
/* CWE-476: NULL Pointer Dereference. */
diagnostic_metadata m;
m.add_cwe (476);
- return warning_meta (rich_loc, m,
- OPT_Wanalyzer_null_dereference,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"dereference of NULL %qE", m_arg);
}
@@ -1106,6 +1128,11 @@ public:
&& m_arg_idx == sub_other.m_arg_idx);
}
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_null_argument;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
/* CWE-476: NULL Pointer Dereference. */
@@ -1115,10 +1142,10 @@ public:
bool warned;
if (zerop (m_arg))
- warned = warning_meta (rich_loc, m, OPT_Wanalyzer_null_argument,
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
"use of NULL where non-null expected");
else
- warned = warning_meta (rich_loc, m, OPT_Wanalyzer_null_argument,
+ warned = warning_meta (rich_loc, m, get_controlling_option (),
"use of NULL %qE where non-null expected",
m_arg);
if (warned)
@@ -1159,12 +1186,17 @@ public:
const char *get_kind () const FINAL OVERRIDE { return "use_after_free"; }
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_use_after_free;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
/* CWE-416: Use After Free. */
diagnostic_metadata m;
m.add_cwe (416);
- return warning_meta (rich_loc, m, OPT_Wanalyzer_use_after_free,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"use after %<%s%> of %qE",
m_deallocator->m_name, m_arg);
}
@@ -1248,15 +1280,20 @@ public:
const char *get_kind () const FINAL OVERRIDE { return "malloc_leak"; }
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_malloc_leak;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
diagnostic_metadata m;
m.add_cwe (401);
if (m_arg)
- return warning_meta (rich_loc, m, OPT_Wanalyzer_malloc_leak,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"leak of %qE", m_arg);
else
- return warning_meta (rich_loc, m, OPT_Wanalyzer_malloc_leak,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"leak of %qs", "<unknown>");
}
@@ -1316,6 +1353,11 @@ public:
&& m_freed_reg == other.m_freed_reg);
}
+ int get_controlling_option () const FINAL OVERRIDE
+ {
+ return OPT_Wanalyzer_free_of_non_heap;
+ }
+
bool emit (rich_location *rich_loc) FINAL OVERRIDE
{
auto_diagnostic_group d;
@@ -1330,13 +1372,13 @@ public:
case MEMSPACE_CODE:
case MEMSPACE_GLOBALS:
case MEMSPACE_READONLY_DATA:
- return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"%<%s%> of %qE which points to memory"
" not on the heap",
m_funcname, m_arg);
break;
case MEMSPACE_STACK:
- return warning_meta (rich_loc, m, OPT_Wanalyzer_free_of_non_heap,
+ return warning_meta (rich_loc, m, get_controlling_option (),
"%<%s%> of %qE which points to memory"
" on the stack",
m_funcname, m_arg);