diff options
author | David Malcolm <dmalcolm@redhat.com> | 2022-11-18 16:59:12 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2022-11-18 16:59:12 -0500 |
commit | 1c4a7881c492790eaad9aec1bcc2c1370f41740f (patch) | |
tree | 0ee3c140f3c6c88b1e34454163a3674e1162f0de /gcc/analyzer/region-model.cc | |
parent | 3142265dedd84c2f3dbf824f2d1b0c182e3c8b3c (diff) | |
download | gcc-1c4a7881c492790eaad9aec1bcc2c1370f41740f.zip gcc-1c4a7881c492790eaad9aec1bcc2c1370f41740f.tar.gz gcc-1c4a7881c492790eaad9aec1bcc2c1370f41740f.tar.bz2 |
analyzer: move more impl_* to known_function
Fix a missing check that the argument to __analyzer_dump_capacity must
be a pointer type (which would otherwise lead to an ICE).
Do so by using the known_function_manager rather than by doing lots of
string matching. Do the same for many other functions.
Doing so moves the type-checking closer to the logic that makes use
of it, by putting them in the same class, rather than splitting them
up between two source files (and sometimes three, e.g. for "pipe").
I hope this reduces the number of missing checks.
gcc/analyzer/ChangeLog:
* analyzer.cc (is_pipe_call_p): Delete.
* analyzer.h (is_pipe_call_p): Delete.
* region-model-impl-calls.cc (call_details::get_location): New.
(class kf_analyzer_break): New, adapted from
region_model::on_stmt_pre.
(region_model::impl_call_analyzer_describe): Convert to...
(class kf_analyzer_describe): ...this.
(region_model::impl_call_analyzer_dump_capacity): Convert to...
(class kf_analyzer_dump_capacity): ...this.
(region_model::impl_call_analyzer_dump_escaped): Convert to...
(class kf_analyzer_dump_escaped): ...this.
(class kf_analyzer_dump_exploded_nodes): New.
(region_model::impl_call_analyzer_dump_named_constant): Convert
to...
(class kf_analyzer_dump_named_constant): ...this.
(class dump_path_diagnostic): Move here from region-model.cc.
(class kf_analyzer_dump_path) New, adapted from
region_model::on_stmt_pre.
(class kf_analyzer_dump_region_model): Likewise.
(region_model::impl_call_analyzer_eval): Convert to...
(class kf_analyzer_eval): ...this.
(region_model::impl_call_analyzer_get_unknown_ptr): Convert to...
(class kf_analyzer_get_unknown_ptr): ...this.
(class known_function_accept): Rename to...
(class kf_accept): ...this.
(class known_function_bind): Rename to...
(class kf_bind): ...this.
(class known_function_connect): Rename to...
(class kf_connect): ...this.
(region_model::impl_call_errno_location): Convert to...
(class kf_errno_location): ...this.
(class known_function_listen): Rename to...
(class kf_listen): ...this.
(region_model::impl_call_pipe): Convert to...
(class kf_pipe): ...this.
(region_model::impl_call_putenv): Convert to...
(class kf_putenv): ...this.
(region_model::impl_call_operator_new): Convert to...
(class kf_operator_new): ...this.
(region_model::impl_call_operator_delete): Convert to...
(class kf_operator_delete): ...this.
(class known_function_socket): Rename to...
(class kf_socket): ...this.
(register_known_functions): Rename param to KFM. Break out
existing known functions into a "POSIX" section, and add "pipe",
"pipe2", and "putenv". Add debugging functions
"__analyzer_break", "__analyzer_describe",
"__analyzer_dump_capacity", "__analyzer_dump_escaped",
"__analyzer_dump_exploded_nodes",
"__analyzer_dump_named_constant", "__analyzer_dump_path",
"__analyzer_dump_region_model", "__analyzer_eval",
"__analyzer_get_unknown_ptr". Add C++ support functions
"operator new", "operator new []", "operator delete", and
"operator delete []".
* region-model.cc (class dump_path_diagnostic): Move to
region-model-impl-calls.cc.
(region_model::on_stmt_pre): Eliminate special-casing of
"__analyzer_describe", "__analyzer_dump_capacity",
"__analyzer_dump_escaped", "__analyzer_dump_named_constant",
"__analyzer_dump_path", "__analyzer_dump_region_model",
"__analyzer_eval", "__analyzer_break",
"__analyzer_dump_exploded_nodes", "__analyzer_get_unknown_ptr",
"__errno_location", "pipe", "pipe2", "putenv", "operator new",
"operator new []", "operator delete", "operator delete []"
"pipe" and "pipe2", handling them instead via the known_functions
mechanism.
* region-model.h (call_details::get_location): New decl.
(region_model::impl_call_analyzer_describe): Delete decl.
(region_model::impl_call_analyzer_dump_capacity): Delete decl.
(region_model::impl_call_analyzer_dump_escaped): Delete decl.
(region_model::impl_call_analyzer_dump_named_constant): Delete decl.
(region_model::impl_call_analyzer_eval): Delete decl.
(region_model::impl_call_analyzer_get_unknown_ptr): Delete decl.
(region_model::impl_call_errno_location): Delete decl.
(region_model::impl_call_pipe): Delete decl.
(region_model::impl_call_putenv): Delete decl.
(region_model::impl_call_operator_new): Delete decl.
(region_model::impl_call_operator_delete): Delete decl.
* sm-fd.cc: Update comments.
gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/analyzer-debugging-fns-1.c: New test.
* gcc.dg/analyzer/attr-const-3.c: Increase the
"analyzer-max-svalue-depth" from 0 to 4 to ensure that
"__analyzer_eval" is recognized.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/analyzer/region-model.cc')
-rw-r--r-- | gcc/analyzer/region-model.cc | 124 |
1 files changed, 2 insertions, 122 deletions
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index e16f66b..81f58a5 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1159,31 +1159,6 @@ region_model::on_assignment (const gassign *assign, region_model_context *ctxt) } } -/* A pending_diagnostic subclass for implementing "__analyzer_dump_path". */ - -class dump_path_diagnostic - : public pending_diagnostic_subclass<dump_path_diagnostic> -{ -public: - int get_controlling_option () const final override - { - return 0; - } - - bool emit (rich_location *richloc) final override - { - inform (richloc, "path"); - return true; - } - - const char *get_kind () const final override { return "dump_path_diagnostic"; } - - bool operator== (const dump_path_diagnostic &) const - { - return true; - } -}; - /* Handle the pre-sm-state part of STMT, modifying this object in-place. Write true to *OUT_TERMINATE_PATH if the path should be terminated. Write true to *OUT_UNKNOWN_SIDE_EFFECTS if the stmt has unknown @@ -1221,55 +1196,8 @@ region_model::on_stmt_pre (const gimple *stmt, anything, for which we don't have a function body, or for which we don't know the fndecl. */ const gcall *call = as_a <const gcall *> (stmt); - - /* Debugging/test support. */ - if (is_special_named_call_p (call, "__analyzer_describe", 2)) - impl_call_analyzer_describe (call, ctxt); - else if (is_special_named_call_p (call, "__analyzer_dump_capacity", 1)) - impl_call_analyzer_dump_capacity (call, ctxt); - else if (is_special_named_call_p (call, "__analyzer_dump_escaped", 0)) - impl_call_analyzer_dump_escaped (call); - else if (is_special_named_call_p (call, - "__analyzer_dump_named_constant", - 1)) - impl_call_analyzer_dump_named_constant (call, ctxt); - else if (is_special_named_call_p (call, "__analyzer_dump_path", 0)) - { - /* Handle the builtin "__analyzer_dump_path" by queuing a - diagnostic at this exploded_node. */ - ctxt->warn (make_unique<dump_path_diagnostic> ()); - } - else if (is_special_named_call_p (call, "__analyzer_dump_region_model", - 0)) - { - /* Handle the builtin "__analyzer_dump_region_model" by dumping - the region model's state to stderr. */ - dump (false); - } - else if (is_special_named_call_p (call, "__analyzer_eval", 1)) - impl_call_analyzer_eval (call, ctxt); - else if (is_special_named_call_p (call, "__analyzer_break", 0)) - { - /* Handle the builtin "__analyzer_break" by triggering a - breakpoint. */ - /* TODO: is there a good cross-platform way to do this? */ - raise (SIGINT); - } - else if (is_special_named_call_p (call, - "__analyzer_dump_exploded_nodes", - 1)) - { - /* This is handled elsewhere. */ - } - else if (is_special_named_call_p (call, "__analyzer_get_unknown_ptr", - 0)) - { - call_details cd (call, this, ctxt); - impl_call_analyzer_get_unknown_ptr (cd); - } - else - *out_unknown_side_effects = on_call_pre (call, ctxt, - out_terminate_path); + *out_unknown_side_effects + = on_call_pre (call, ctxt, out_terminate_path); } break; @@ -2293,11 +2221,6 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, impl_call_realloc (cd); return false; } - else if (is_named_call_p (callee_fndecl, "__errno_location", call, 0)) - { - impl_call_errno_location (cd); - return false; - } else if (is_named_call_p (callee_fndecl, "error")) { if (impl_call_error (cd, 3, out_terminate_path)) @@ -2334,20 +2257,6 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, impl_call_memset (cd); return false; } - else if (is_pipe_call_p (callee_fndecl, "pipe", call, 1) - || is_pipe_call_p (callee_fndecl, "pipe2", call, 2)) - { - /* Handle in "on_call_post"; bail now so that fd array - is left untouched so that we can detect use-of-uninit - for the case where the call fails. */ - return false; - } - else if (is_named_call_p (callee_fndecl, "putenv", call, 1) - && POINTER_TYPE_P (cd.get_arg_type (0))) - { - impl_call_putenv (cd); - return false; - } else if (is_named_call_p (callee_fndecl, "strchr", call, 2) && POINTER_TYPE_P (cd.get_arg_type (0))) { @@ -2360,22 +2269,6 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, impl_call_strlen (cd); return false; } - else if (is_named_call_p (callee_fndecl, "operator new", call, 1)) - { - impl_call_operator_new (cd); - return false; - } - else if (is_named_call_p (callee_fndecl, "operator new []", call, 1)) - { - impl_call_operator_new (cd); - return false; - } - else if (is_named_call_p (callee_fndecl, "operator delete", call, 1) - || is_named_call_p (callee_fndecl, "operator delete", call, 2) - || is_named_call_p (callee_fndecl, "operator delete []", call, 1)) - { - /* Handle in "on_call_post". */ - } else if (const known_function *kf = get_known_function (callee_fndecl)) { if (kf->matches_call_types_p (cd)) @@ -2418,19 +2311,6 @@ region_model::on_call_post (const gcall *call, impl_call_free (cd); return; } - if (is_named_call_p (callee_fndecl, "operator delete", call, 1) - || is_named_call_p (callee_fndecl, "operator delete", call, 2) - || is_named_call_p (callee_fndecl, "operator delete []", call, 1)) - { - impl_call_operator_delete (cd); - return; - } - else if (is_pipe_call_p (callee_fndecl, "pipe", call, 1) - || is_pipe_call_p (callee_fndecl, "pipe2", call, 2)) - { - impl_call_pipe (cd); - return; - } else if (is_named_call_p (callee_fndecl, "strchr", call, 2) && POINTER_TYPE_P (cd.get_arg_type (0))) { |