diff options
author | Martin Liska <mliska@suse.cz> | 2022-11-07 08:24:48 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-11-07 08:24:48 +0100 |
commit | 1b09b78ee61bd921ae78ebd0f7905b95b9e1c903 (patch) | |
tree | 9c04b59cdd2cd460f0727501d15402d31ffcf5a4 /gcc/analyzer | |
parent | 1eb021edb27e26f95cda63df121f6bc951647599 (diff) | |
parent | c4f8f8afd07680f9e718de1331cd09607bdd9ac8 (diff) | |
download | gcc-1b09b78ee61bd921ae78ebd0f7905b95b9e1c903.zip gcc-1b09b78ee61bd921ae78ebd0f7905b95b9e1c903.tar.gz gcc-1b09b78ee61bd921ae78ebd0f7905b95b9e1c903.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/analyzer')
47 files changed, 774 insertions, 448 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 6e6b056..f308f64 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,244 @@ +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * analyzer.h: Use std::unique_ptr for state machines from plugins. + * engine.cc: Likewise. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * analyzer.h: Use std::unique_ptr for known functions. + * engine.cc: Likewise. + * known-function-manager.cc: Likewise. + * known-function-manager.h: Likewise. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * analysis-plan.cc: Define INCLUDE_MEMORY before including + system.h. + * analyzer-pass.cc: Likewise. + * analyzer-selftests.cc: Likewise. + * analyzer.cc: Likewise. + * analyzer.h: Use std::unique_ptr in bifurcation code. + * call-string.cc: Define INCLUDE_MEMORY before including system.h. + * complexity.cc: Likewise. + * engine.cc: Use std::unique_ptr in bifurcation code. + * exploded-graph.h: Likewise. + * known-function-manager.cc: Define INCLUDE_MEMORY before + including system.h. + * region-model-impl-calls.cc: Use std::unique_ptr in bifurcation + code. + * region-model.cc: Likewise. + * region-model.h: Likewise. + * supergraph.cc: Define INCLUDE_MEMORY before including system.h. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * call-info.cc: Use std::unique_ptr for checker_event. + * checker-path.cc: Likewise. + * checker-path.h: Likewise. + * diagnostic-manager.cc: Likewise. + * engine.cc: Likewise. + * pending-diagnostic.cc: Likewise. + * sm-signal.cc: Likewise. + * varargs.cc: Likewise. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * diagnostic-manager.cc: Include "make-unique.h". + Use std::unique_ptr for feasibility_problems and exploded_path. + Delete explicit saved_diagnostic dtor. + * diagnostic-manager.h: Likewise. + * engine.cc: Likewise. + * exploded-graph.h: Likewise. + * feasible-graph.cc: Likewise. + * feasible-graph.h: Likewise. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * checker-path.cc (rewind_event::rewind_event): Update for usage of + std::unique_ptr on custom_edge_info. + * engine.cc (exploded_node::on_longjmp): Likewise. + (exploded_edge::exploded_edge): Likewise. + (exploded_edge::~exploded_edge): Delete. + (exploded_graph::add_function_entry): Update for usage of + std::unique_ptr on custom_edge_info. + (exploded_graph::add_edge): Likewise. + (add_tainted_args_callback): Likewise. + (exploded_graph::maybe_create_dynamic_call): Likewise. + (exploded_graph::process_node): Likewise. + * exploded-graph.h (exploded_edge::~exploded_edge): Delete. + (exploded_edge::m_custom_info): Use std::unique_ptr. + (exploded_edge::add_edge): Likewise. + * sm-signal.cc (register_signal_handler::impl_transition): Use + make_unique. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * diagnostic-manager.cc (saved_diagnostic::saved_diagnostic): Make + stmt_finder const. + (saved_diagnostic::~saved_diagnostic): Remove explicit delete of + m_stmt_finder. + (diagnostic_manager::add_diagnostic): Make stmt_finder const. + * diagnostic-manager.h (saved_diagnostic::saved_diagnostic): + Likewise. + (saved_diagnostic::m_stmt_finder): Convert to std::unique_ptr. + (diagnostic_manager::add_diagnostic): Make stmt_finder const. + * engine.cc (impl_sm_context::impl_sm_context): Likewise. + (impl_sm_context::m_stmt_finder): Likewise. + (leak_stmt_finder::clone): Convert return type to std::unique_ptr. + * exploded-graph.h (stmt_finder::clone): Likewise. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + * call-info.cc: Add define of INCLUDE_MEMORY. + * call-summary.cc: Likewise. + * checker-path.cc: Likewise. + * constraint-manager.cc: Likewise. + * diagnostic-manager.cc: Likewise. + (saved_diagnostic::saved_diagnostic): Use std::unique_ptr for + param d and field m_d. + (saved_diagnostic::~saved_diagnostic): Remove explicit delete of m_d. + (saved_diagnostic::add_note): Use std::unique_ptr for + param pn. + (saved_diagnostic::get_pending_diagnostic): Update for conversion + of m_sd.m_d to unique_ptr. + (diagnostic_manager::add_diagnostic): Use std::unique_ptr for + param d. Remove explicit deletion. + (diagnostic_manager::add_note): Use std::unique_ptr for param pn. + (diagnostic_manager::emit_saved_diagnostic): Update for conversion + of m_sd.m_d to unique_ptr. + (null_assignment_sm_context::warn): Use std::unique_ptr for + param d. Remove explicit deletion. + * diagnostic-manager.h (saved_diagnostic::saved_diagnostic): Use + std::unique_ptr for param d. + (saved_diagnostic::add_note): Likewise for param pn. + (saved_diagnostic::m_d): Likewise. + (diagnostic_manager::add_diagnostic): Use std::unique_ptr for + param d. + (diagnostic_manager::add_note): Use std::unique_ptr for param pn. + * engine.cc: Include "make-unique.h". + (impl_region_model_context::warn): Update to use std::unique_ptr + for param, removing explicit deletion. + (impl_region_model_context::add_note): Likewise. + (impl_sm_context::warn): Update to use std::unique_ptr + for param. + (impl_region_model_context::on_state_leak): Likewise for result of + on_leak. + (exploded_node::on_longjmp): Use make_unique when creating + pending_diagnostic. + (exploded_graph::process_node): Likewise. + * exploded-graph.h (impl_region_model_context::warn): Update to + use std::unique_ptr for param. + (impl_region_model_context::add_note): Likewise. + * feasible-graph.cc: Add define of INCLUDE_MEMORY. + * pending-diagnostic.cc: Likewise. + * pending-diagnostic.h: Include analyzer.sm.h" + * program-point.cc: Add define of INCLUDE_MEMORY. + * program-state.cc: Likewise. + * region-model-asm.cc: Likewise. + * region-model-impl-calls.cc: Likewise. Include "make-unique.h". + (region_model::impl_call_putenv): Use make_unique when creating + pending_diagnostic. + * region-model-manager.cc: Add define of INCLUDE_MEMORY. + * region-model-reachability.cc: Likewise. + * region-model.cc: Likewise. Include "make-unique.h". + (region_model::get_gassign_result): Use make_unique when creating + pending_diagnostic. + (region_model::check_for_poison): Likewise. + (region_model::on_stmt_pre): Likewise. + (region_model::check_symbolic_bounds): Likewise. + (region_model::check_region_bounds): Likewise. + (annotating_ctxt: make_note): Use std::unique_ptr for result. + (region_model::deref_rvalue): Use make_unique when creating + pending_diagnostic. + (region_model::check_for_writable_region): Likewise. + (region_model::check_region_size): Likewise. + (region_model::check_dynamic_size_for_floats): Likewise. + (region_model::maybe_complain_about_infoleak): Likewise. + (noop_region_model_context::add_note): Use std::unique_ptr for + param. Remove explicit deletion. + * region-model.h: Include "analyzer/pending-diagnostic.h". + (region_model_context::warn): Convert param to std::unique_ptr. + (region_model_context::add_note): Likewise. + (noop_region_model_context::warn): Likewise. + (noop_region_model_context::add_note): Likewise. + (region_model_context_decorator::warn): Likewise. + (region_model_context_decorator::add_note): Likewise. + (note_adding_context::warn): Likewise. + (note_adding_context::make_note): Likewise for return type. + (test_region_model_context::warn): Convert param to + std::unique_ptr. + * region.cc: Add define of INCLUDE_MEMORY. + * sm-fd.cc: Likewise. Include "make-unique.h". + (fd_state_machine::check_for_fd_attrs): Use make_unique when + creating pending_diagnostics. + (fd_state_machine::on_open): Likewise. + (fd_state_machine::on_creat): Likewise. + (fd_state_machine::check_for_dup): Likewise. + (fd_state_machine::on_close): Likewise. + (fd_state_machine::check_for_open_fd): Likewise. + (fd_state_machine::on_leak): Likewise, converting return type to + std::unique_ptr. + * sm-file.cc: Add define of INCLUDE_MEMORY. Include + "make-unique.h". + (fileptr_state_machine::on_stmt): Use make_unique when creating + pending_diagnostic. + (fileptr_state_machine::on_leak): Likewise, converting return type + to std::unique_ptr. + * sm-malloc.cc: Add define of INCLUDE_MEMORY. Include + "make-unique.h". + (malloc_state_machine::on_stmt): Use make_unique when creating + pending_diagnostic. + (malloc_state_machine::handle_free_of_non_heap): Likewise. + (malloc_state_machine::on_deallocator_call): Likewise. + (malloc_state_machine::on_realloc_call): Likewise. + (malloc_state_machine::on_leak): Likewise, converting return type + to std::unique_ptr. + * sm-pattern-test.cc: Add define of INCLUDE_MEMORY. Include + "make-unique.h". + (pattern_test_state_machine::on_condition): Use make_unique when + creating pending_diagnostic. + * sm-sensitive.cc: Add define of INCLUDE_MEMORY. Include + "make-unique.h". + (sensitive_state_machine::warn_for_any_exposure): Use make_unique + when creating pending_diagnostic. + * sm-signal.cc: Add define of INCLUDE_MEMORY. Include + "make-unique.h". + (signal_state_machine::on_stmt): Use make_unique when creating + pending_diagnostic. + * sm-taint.cc: Add define of INCLUDE_MEMORY. Include + "make-unique.h". + (taint_state_machine::check_for_tainted_size_arg): Use make_unique + when creating pending_diagnostic. + (taint_state_machine::check_for_tainted_divisor): Likewise. + (region_model::check_region_for_taint): Likewise. + (region_model::check_dynamic_size_for_taint): Likewise. + * sm.cc: Add define of INCLUDE_MEMORY. Include + "analyzer/pending-diagnostic.h". + (state_machine::on_leak): Move here from sm.h, changing return + type to std::unique_ptr. + * sm.h (state_machine::on_leak): Change return type to + std::unique_ptr. Move defn of base impl to sm.cc + (sm_context::warn): Convert param d to std_unique_ptr. + * state-purge.cc: Add define of INCLUDE_MEMORY. + * store.cc: Likewise. + * svalue.cc: Likewise. + * trimmed-graph.cc: Likewise. + * varargs.cc: Likewise. Include "make-unique.h". + (va_list_state_machine::check_for_ended_va_list): Use make_unique + when creating pending_diagnostic. + (va_list_state_machine::on_leak): Likewise, converting return type + to std::unique_ptr. + (region_model::impl_call_va_arg): Use make_unique when creating + pending_diagnostic. + +2022-11-03 David Malcolm <dmalcolm@redhat.com> + + PR analyzer/107486 + * analyzer.cc (is_pipe_call_p): New. + * analyzer.h (is_pipe_call_p): New decl. + * region-model.cc (region_model::on_call_pre): Use it. + (region_model::on_call_post): Likewise. + 2022-10-26 David Malcolm <dmalcolm@redhat.com> * sm-fd.cc (fd_state_machine::on_open): Transition to "unchecked" diff --git a/gcc/analyzer/analysis-plan.cc b/gcc/analyzer/analysis-plan.cc index a4a42c5..aa75bd6 100644 --- a/gcc/analyzer/analysis-plan.cc +++ b/gcc/analyzer/analysis-plan.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/analyzer-pass.cc b/gcc/analyzer/analyzer-pass.cc index fc7098d..423595f 100644 --- a/gcc/analyzer/analyzer-pass.cc +++ b/gcc/analyzer/analyzer-pass.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "context.h" diff --git a/gcc/analyzer/analyzer-selftests.cc b/gcc/analyzer/analyzer-selftests.cc index 278c245..028cc5e 100644 --- a/gcc/analyzer/analyzer-selftests.cc +++ b/gcc/analyzer/analyzer-selftests.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc index 8a2a773..899202b 100644 --- a/gcc/analyzer/analyzer.cc +++ b/gcc/analyzer/analyzer.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -379,6 +380,22 @@ is_longjmp_call_p (const gcall *call) return false; } +/* Return true if this is a "pipe" call. */ + +bool +is_pipe_call_p (const_tree fndecl, const char *funcname, + const gcall *call, unsigned int num_args) +{ + if (!is_named_call_p (fndecl, funcname, call, num_args)) + return false; + + /* We require a pointer for the initial argument. */ + if (!POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0)))) + return false; + + return true; +} + /* For a CALL that matched is_special_named_call_p or is_named_call_p for some name, return a name for the called function suitable for use in diagnostics (stripping the leading underscores). */ diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index a2d79e4..c0041c3 100644 --- a/gcc/analyzer/analyzer.h +++ b/gcc/analyzer/analyzer.h @@ -242,9 +242,9 @@ public: class plugin_analyzer_init_iface { public: - virtual void register_state_machine (state_machine *) = 0; + virtual void register_state_machine (std::unique_ptr<state_machine>) = 0; virtual void register_known_function (const char *name, - known_function *) = 0; + std::unique_ptr<known_function>) = 0; virtual logger *get_logger () const = 0; }; @@ -300,9 +300,8 @@ class path_context public: virtual ~path_context () {} - /* Hook for clients to split state with a non-standard path. - Take ownership of INFO. */ - virtual void bifurcate (custom_edge_info *info) = 0; + /* Hook for clients to split state with a non-standard path. */ + virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0; /* Hook for clients to terminate the standard path. */ virtual void terminate_path () = 0; @@ -324,6 +323,8 @@ extern bool is_std_named_call_p (const_tree fndecl, const char *funcname, const gcall *call, unsigned int num_args); extern bool is_setjmp_call_p (const gcall *call); extern bool is_longjmp_call_p (const gcall *call); +extern bool is_pipe_call_p (const_tree fndecl, const char *funcname, + const gcall *call, unsigned int num_args); extern const char *get_user_facing_name (const gcall *call); diff --git a/gcc/analyzer/call-info.cc b/gcc/analyzer/call-info.cc index 56059ac..ffdab73 100644 --- a/gcc/analyzer/call-info.cc +++ b/gcc/analyzer/call-info.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -54,6 +55,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/diagnostic-manager.h" #include "analyzer/exploded-graph.h" #include "analyzer/call-info.h" +#include "make-unique.h" #if ENABLE_ANALYZER @@ -112,10 +114,10 @@ call_info::add_events_to_path (checker_path *emission_path, tree caller_fndecl = src_point.get_fndecl (); const int stack_depth = src_point.get_stack_depth (); - emission_path->add_event (new call_event (get_call_stmt ()->location, - caller_fndecl, - stack_depth, - this)); + emission_path->add_event (make_unique<call_event> (get_call_stmt ()->location, + caller_fndecl, + stack_depth, + this)); } /* Recreate a call_details instance from this call_info. */ diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc index f0a30d9..5caf921 100644 --- a/gcc/analyzer/call-string.cc +++ b/gcc/analyzer/call-string.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "pretty-print.h" diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc index 12ef82d..ebc7b50 100644 --- a/gcc/analyzer/call-summary.cc +++ b/gcc/analyzer/call-summary.cc @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc index 371111b..40f9ccfe 100644 --- a/gcc/analyzer/checker-path.cc +++ b/gcc/analyzer/checker-path.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -55,6 +56,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/diagnostic-manager.h" #include "analyzer/checker-path.h" #include "analyzer/exploded-graph.h" +#include "make-unique.h" #if ENABLE_ANALYZER @@ -1036,7 +1038,7 @@ rewind_event::rewind_event (const exploded_edge *eedge, m_rewind_info (rewind_info), m_eedge (eedge) { - gcc_assert (m_eedge->m_custom_info == m_rewind_info); + gcc_assert (m_eedge->m_custom_info.get () == m_rewind_info); } /* class rewind_from_longjmp_event : public rewind_event. */ @@ -1261,16 +1263,16 @@ checker_path::add_region_creation_events (const region *reg, if (const svalue *capacity_sval = model->get_capacity (reg)) capacity = model->get_representative_tree (capacity_sval); - add_event (new region_creation_event (reg, capacity, RCE_MEM_SPACE, - loc, fndecl, depth)); + add_event (make_unique<region_creation_event> (reg, capacity, RCE_MEM_SPACE, + loc, fndecl, depth)); if (capacity) - add_event (new region_creation_event (reg, capacity, RCE_CAPACITY, - loc, fndecl, depth)); + add_event (make_unique<region_creation_event> (reg, capacity, RCE_CAPACITY, + loc, fndecl, depth)); if (debug) - add_event (new region_creation_event (reg, capacity, RCE_DEBUG, - loc, fndecl, depth)); + add_event (make_unique<region_creation_event> (reg, capacity, RCE_DEBUG, + loc, fndecl, depth)); } /* Add a warning_event to the end of this path. */ @@ -1280,12 +1282,12 @@ checker_path::add_final_event (const state_machine *sm, const exploded_node *enode, const gimple *stmt, tree var, state_machine::state_t state) { - checker_event *end_of_path - = new warning_event (get_stmt_location (stmt, enode->get_function ()), - enode->get_function ()->decl, - enode->get_stack_depth (), - sm, var, state); - add_event (end_of_path); + add_event + (make_unique<warning_event> (get_stmt_location (stmt, + enode->get_function ()), + enode->get_function ()->decl, + enode->get_stack_depth (), + sm, var, state)); } void diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h index 5d00934..c8de5c9 100644 --- a/gcc/analyzer/checker-path.h +++ b/gcc/analyzer/checker-path.h @@ -631,9 +631,9 @@ public: void maybe_log (logger *logger, const char *desc) const; - void add_event (checker_event *event) + void add_event (std::unique_ptr<checker_event> event) { - m_events.safe_push (event); + m_events.safe_push (event.release ()); } void delete_event (int idx) diff --git a/gcc/analyzer/complexity.cc b/gcc/analyzer/complexity.cc index 39fbbc1..2756f96 100644 --- a/gcc/analyzer/complexity.cc +++ b/gcc/analyzer/complexity.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index 96ae073..b4e51b0 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 695bde5..e775475 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -55,6 +56,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/feasible-graph.h" #include "analyzer/checker-path.h" #include "analyzer/reachability.h" +#include "make-unique.h" #if ENABLE_ANALYZER @@ -84,21 +86,24 @@ public: logger *get_logger () const { return m_eg.get_logger (); } - exploded_path *get_best_epath (const exploded_node *target_enode, - const char *desc, unsigned diag_idx, - feasibility_problem **out_problem); + std::unique_ptr<exploded_path> + get_best_epath (const exploded_node *target_enode, + const char *desc, unsigned diag_idx, + std::unique_ptr<feasibility_problem> *out_problem); private: DISABLE_COPY_AND_ASSIGN(epath_finder); - exploded_path *explore_feasible_paths (const exploded_node *target_enode, - const char *desc, unsigned diag_idx); - bool process_worklist_item (feasible_worklist *worklist, - const trimmed_graph &tg, - feasible_graph *fg, - const exploded_node *target_enode, - unsigned diag_idx, - exploded_path **out_best_path) const; + std::unique_ptr<exploded_path> + explore_feasible_paths (const exploded_node *target_enode, + const char *desc, unsigned diag_idx); + bool + process_worklist_item (feasible_worklist *worklist, + const trimmed_graph &tg, + feasible_graph *fg, + const exploded_node *target_enode, + unsigned diag_idx, + std::unique_ptr<exploded_path> *out_best_path) const; void dump_trimmed_graph (const exploded_node *target_enode, const char *desc, unsigned diag_idx, const trimmed_graph &tg, @@ -131,10 +136,10 @@ private: Write any feasibility_problem to *OUT_PROBLEM. */ -exploded_path * +std::unique_ptr<exploded_path> epath_finder::get_best_epath (const exploded_node *enode, const char *desc, unsigned diag_idx, - feasibility_problem **out_problem) + std::unique_ptr<feasibility_problem> *out_problem) { logger *logger = get_logger (); LOG_SCOPE (logger); @@ -155,7 +160,8 @@ epath_finder::get_best_epath (const exploded_node *enode, /* Attempt to find the shortest feasible path using feasible_graph. */ if (logger) logger->log ("trying to find shortest feasible path"); - if (exploded_path *epath = explore_feasible_paths (enode, desc, diag_idx)) + if (std::unique_ptr<exploded_path> epath + = explore_feasible_paths (enode, desc, diag_idx)) { if (logger) logger->log ("accepting %qs at EN: %i, SN: %i (sd: %i)" @@ -183,8 +189,8 @@ epath_finder::get_best_epath (const exploded_node *enode, if (logger) logger->log ("trying to find shortest path ignoring feasibility"); gcc_assert (m_sep); - exploded_path *epath - = new exploded_path (m_sep->get_shortest_path (enode)); + std::unique_ptr<exploded_path> epath + = make_unique<exploded_path> (m_sep->get_shortest_path (enode)); if (epath->feasible_p (logger, out_problem, m_eg.get_engine (), &m_eg)) { if (logger) @@ -366,7 +372,7 @@ private: continue forever without reaching the target), or - getting monotonically closer to the termination threshold. */ -exploded_path * +std::unique_ptr<exploded_path> epath_finder::explore_feasible_paths (const exploded_node *target_enode, const char *desc, unsigned diag_idx) { @@ -404,7 +410,7 @@ epath_finder::explore_feasible_paths (const exploded_node *target_enode, a limit. */ /* Set this if we find a feasible path to TARGET_ENODE. */ - exploded_path *best_path = NULL; + std::unique_ptr<exploded_path> best_path = NULL; { auto_checking_feasibility sentinel (mgr); @@ -446,12 +452,13 @@ epath_finder::explore_feasible_paths (const exploded_node *target_enode, to TARGET_ENODE. */ bool -epath_finder::process_worklist_item (feasible_worklist *worklist, - const trimmed_graph &tg, - feasible_graph *fg, - const exploded_node *target_enode, - unsigned diag_idx, - exploded_path **out_best_path) const +epath_finder:: +process_worklist_item (feasible_worklist *worklist, + const trimmed_graph &tg, + feasible_graph *fg, + const exploded_node *target_enode, + unsigned diag_idx, + std::unique_ptr<exploded_path> *out_best_path) const { logger *logger = get_logger (); @@ -634,18 +641,18 @@ epath_finder::dump_feasible_path (const exploded_node *target_enode, saved_diagnostic::saved_diagnostic (const state_machine *sm, const exploded_node *enode, const supernode *snode, const gimple *stmt, - stmt_finder *stmt_finder, + const stmt_finder *stmt_finder, tree var, const svalue *sval, state_machine::state_t state, - pending_diagnostic *d, + std::unique_ptr<pending_diagnostic> d, unsigned idx) : m_sm (sm), m_enode (enode), m_snode (snode), m_stmt (stmt), /* stmt_finder could be on-stack; we want our own copy that can outlive that. */ m_stmt_finder (stmt_finder ? stmt_finder->clone () : NULL), m_var (var), m_sval (sval), m_state (state), - m_d (d), m_trailing_eedge (NULL), + m_d (std::move (d)), m_trailing_eedge (NULL), m_idx (idx), m_best_epath (NULL), m_problem (NULL), m_notes () @@ -657,16 +664,6 @@ saved_diagnostic::saved_diagnostic (const state_machine *sm, gcc_assert (m_enode); } -/* saved_diagnostic's dtor. */ - -saved_diagnostic::~saved_diagnostic () -{ - delete m_stmt_finder; - delete m_d; - delete m_best_epath; - delete m_problem; -} - bool saved_diagnostic::operator== (const saved_diagnostic &other) const { @@ -689,10 +686,10 @@ saved_diagnostic::operator== (const saved_diagnostic &other) const /* Add PN to this diagnostic, taking ownership of it. */ void -saved_diagnostic::add_note (pending_note *pn) +saved_diagnostic::add_note (std::unique_ptr<pending_note> pn) { gcc_assert (pn); - m_notes.safe_push (pn); + m_notes.safe_push (pn.release ()); } /* Return a new json::object of the form @@ -809,8 +806,6 @@ saved_diagnostic::calc_best_epath (epath_finder *pf) { logger *logger = pf->get_logger (); LOG_SCOPE (logger); - delete m_best_epath; - delete m_problem; m_problem = NULL; m_best_epath = pf->get_best_epath (m_enode, m_d->get_kind (), m_idx, @@ -896,7 +891,7 @@ public: pending_diagnostic *get_pending_diagnostic () const { - return m_sd.m_d; + return m_sd.m_d.get (); } bool reachable_from_p (const exploded_node *src_enode) const @@ -955,18 +950,17 @@ diagnostic_manager::diagnostic_manager (logger *logger, engine *eng, } /* Queue pending_diagnostic D at ENODE for later emission. - Return true/false signifying if the diagnostic was actually added. - Take ownership of D (or delete it). */ + Return true/false signifying if the diagnostic was actually added. */ bool diagnostic_manager::add_diagnostic (const state_machine *sm, exploded_node *enode, const supernode *snode, const gimple *stmt, - stmt_finder *finder, + const stmt_finder *finder, tree var, const svalue *sval, state_machine::state_t state, - pending_diagnostic *d) + std::unique_ptr<pending_diagnostic> d) { LOG_FUNC (get_logger ()); @@ -987,7 +981,6 @@ diagnostic_manager::add_diagnostic (const state_machine *sm, if (get_logger ()) get_logger ()->log ("rejecting disabled warning %qs", d->get_kind ()); - delete d; m_num_disabled_diagnostics++; return false; } @@ -995,13 +988,13 @@ diagnostic_manager::add_diagnostic (const state_machine *sm, saved_diagnostic *sd = new saved_diagnostic (sm, enode, snode, stmt, finder, var, sval, - state, d, m_saved_diagnostics.length ()); + state, std::move (d), m_saved_diagnostics.length ()); m_saved_diagnostics.safe_push (sd); enode->add_diagnostic (sd); if (get_logger ()) log ("adding saved diagnostic %i at SN %i to EN %i: %qs", sd->get_index (), - snode->m_index, enode->m_index, d->get_kind ()); + snode->m_index, enode->m_index, sd->m_d->get_kind ()); return true; } @@ -1012,18 +1005,18 @@ diagnostic_manager::add_diagnostic (const state_machine *sm, bool diagnostic_manager::add_diagnostic (exploded_node *enode, const supernode *snode, const gimple *stmt, - stmt_finder *finder, - pending_diagnostic *d) + const stmt_finder *finder, + std::unique_ptr<pending_diagnostic> d) { gcc_assert (enode); return add_diagnostic (NULL, enode, snode, stmt, finder, NULL_TREE, - NULL, 0, d); + NULL, 0, std::move (d)); } /* Add PN to the most recent saved_diagnostic. */ void -diagnostic_manager::add_note (pending_note *pn) +diagnostic_manager::add_note (std::unique_ptr<pending_note> pn) { LOG_FUNC (get_logger ()); gcc_assert (pn); @@ -1031,7 +1024,7 @@ diagnostic_manager::add_note (pending_note *pn) /* Get most recent saved_diagnostic. */ gcc_assert (m_saved_diagnostics.length () > 0); saved_diagnostic *sd = m_saved_diagnostics[m_saved_diagnostics.length () - 1]; - sd->add_note (pn); + sd->add_note (std::move (pn)); } /* Return a new json::object of the form @@ -1386,13 +1379,13 @@ diagnostic_manager::emit_saved_diagnostic (const exploded_graph &eg, emission_path.inject_any_inlined_call_events (get_logger ()); - emission_path.prepare_for_emission (sd.m_d); + emission_path.prepare_for_emission (sd.m_d.get ()); 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 locations of events. */ - emission_path.fixup_locations (sd.m_d); + emission_path.fixup_locations (sd.m_d.get ()); gcc_rich_location rich_loc (loc); rich_loc.set_path (&emission_path); @@ -1566,15 +1559,16 @@ public: int stack_depth = src_stack_depth; - m_emission_path->add_event (new state_change_event (supernode, - stmt, - stack_depth, - sm, - NULL, - src_sm_val, - dst_sm_val, - NULL, - dst_state)); + m_emission_path->add_event + (make_unique<state_change_event> (supernode, + stmt, + stack_depth, + sm, + NULL, + src_sm_val, + dst_sm_val, + NULL, + dst_state)); return false; } @@ -1609,15 +1603,16 @@ public: if (!stmt) return false; - m_emission_path->add_event (new state_change_event (supernode, - stmt, - stack_depth, - sm, - sval, - src_sm_val, - dst_sm_val, - dst_origin_sval, - dst_state)); + m_emission_path->add_event + (make_unique<state_change_event> (supernode, + stmt, + stack_depth, + sm, + sval, + src_sm_val, + dst_sm_val, + dst_origin_sval, + dst_state)); return false; } @@ -1750,14 +1745,15 @@ struct null_assignment_sm_context : public sm_context const supernode *supernode = m_point->get_supernode (); int stack_depth = m_point->get_stack_depth (); - m_emission_path->add_event (new state_change_event (supernode, - m_stmt, - stack_depth, - m_sm, - var_new_sval, - from, to, - NULL, - *m_new_state)); + m_emission_path->add_event + (make_unique<state_change_event> (supernode, + m_stmt, + stack_depth, + m_sm, + var_new_sval, + from, to, + NULL, + *m_new_state)); } void set_next_state (const gimple *stmt, @@ -1772,25 +1768,24 @@ struct null_assignment_sm_context : public sm_context const supernode *supernode = m_point->get_supernode (); int stack_depth = m_point->get_stack_depth (); - m_emission_path->add_event (new state_change_event (supernode, - m_stmt, - stack_depth, - m_sm, - sval, - from, to, - NULL, - *m_new_state)); + m_emission_path->add_event + (make_unique<state_change_event> (supernode, + m_stmt, + stack_depth, + m_sm, + sval, + from, to, + NULL, + *m_new_state)); } void warn (const supernode *, const gimple *, - tree, pending_diagnostic *d) final override + tree, std::unique_ptr<pending_diagnostic>) final override { - delete d; } void warn (const supernode *, const gimple *, - const svalue *, pending_diagnostic *d) final override + const svalue *, std::unique_ptr<pending_diagnostic>) final override { - delete d; } tree get_diagnostic_tree (tree expr) final override @@ -1916,7 +1911,7 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb, if (dst_point.get_supernode ()->entry_p ()) { emission_path->add_event - (new function_entry_event + (make_unique<function_entry_event> (dst_point.get_supernode ()->get_start_location (), dst_point.get_fndecl (), dst_stack_depth)); @@ -1952,16 +1947,16 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb, const gcall *call = dyn_cast <const gcall *> (stmt); if (call && is_setjmp_call_p (call)) emission_path->add_event - (new setjmp_event (stmt->location, - dst_node, - dst_point.get_fndecl (), - dst_stack_depth, - call)); + (make_unique<setjmp_event> (stmt->location, + dst_node, + dst_point.get_fndecl (), + dst_stack_depth, + call)); else emission_path->add_event - (new statement_event (stmt, - dst_point.get_fndecl (), - dst_stack_depth, dst_state)); + (make_unique<statement_event> (stmt, + dst_point.get_fndecl (), + dst_stack_depth, dst_state)); /* Create state change events for assignment to NULL. Iterate through the stmts in dst_enode, adding state change @@ -2051,11 +2046,12 @@ diagnostic_manager::add_events_for_eedge (const path_builder &pb, "this path would have been rejected as infeasible" " at this edge: "); pb.get_feasibility_problem ()->dump_to_pp (&pp); - emission_path->add_event (new precanned_custom_event - (dst_point.get_location (), - dst_point.get_fndecl (), - dst_stack_depth, - pp_formatted_text (&pp))); + emission_path->add_event + (make_unique<precanned_custom_event> + (dst_point.get_location (), + dst_point.get_fndecl (), + dst_stack_depth, + pp_formatted_text (&pp))); } } @@ -2166,17 +2162,18 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb, case SUPEREDGE_CFG_EDGE: { emission_path->add_event - (new start_cfg_edge_event (eedge, - (last_stmt - ? last_stmt->location - : UNKNOWN_LOCATION), - src_point.get_fndecl (), - src_stack_depth)); + (make_unique<start_cfg_edge_event> (eedge, + (last_stmt + ? last_stmt->location + : UNKNOWN_LOCATION), + src_point.get_fndecl (), + src_stack_depth)); emission_path->add_event - (new end_cfg_edge_event (eedge, - dst_point.get_supernode ()->get_start_location (), - dst_point.get_fndecl (), - dst_stack_depth)); + (make_unique<end_cfg_edge_event> + (eedge, + dst_point.get_supernode ()->get_start_location (), + dst_point.get_fndecl (), + dst_stack_depth)); } break; @@ -2189,12 +2186,12 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb, /* TODO: add a subclass for this, or generate events for the summary. */ emission_path->add_event - (new debug_event ((last_stmt - ? last_stmt->location - : UNKNOWN_LOCATION), - src_point.get_fndecl (), - src_stack_depth, - "call summary")); + (make_unique<debug_event> ((last_stmt + ? last_stmt->location + : UNKNOWN_LOCATION), + src_point.get_fndecl (), + src_stack_depth, + "call summary")); } break; @@ -2205,12 +2202,12 @@ diagnostic_manager::add_events_for_superedge (const path_builder &pb, const gcall *call_stmt = return_edge->get_call_stmt (); emission_path->add_event - (new return_event (eedge, - (call_stmt - ? call_stmt->location - : UNKNOWN_LOCATION), - dst_point.get_fndecl (), - dst_stack_depth)); + (make_unique<return_event> (eedge, + (call_stmt + ? call_stmt->location + : UNKNOWN_LOCATION), + dst_point.get_fndecl (), + dst_stack_depth)); } break; } diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h index 266eed8..4862cf4 100644 --- a/gcc/analyzer/diagnostic-manager.h +++ b/gcc/analyzer/diagnostic-manager.h @@ -33,16 +33,15 @@ public: saved_diagnostic (const state_machine *sm, const exploded_node *enode, const supernode *snode, const gimple *stmt, - stmt_finder *stmt_finder, + const stmt_finder *stmt_finder, tree var, const svalue *sval, state_machine::state_t state, - pending_diagnostic *d, + std::unique_ptr<pending_diagnostic> d, unsigned idx); - ~saved_diagnostic (); bool operator== (const saved_diagnostic &other) const; - void add_note (pending_note *pn); + void add_note (std::unique_ptr<pending_note> pn); json::object *to_json () const; @@ -51,11 +50,11 @@ public: const feasibility_problem *get_feasibility_problem () const { - return m_problem; + return m_problem.get (); } bool calc_best_epath (epath_finder *pf); - const exploded_path *get_best_epath () const { return m_best_epath; } + const exploded_path *get_best_epath () const { return m_best_epath.get (); } unsigned get_epath_length () const; void add_duplicate (saved_diagnostic *other); @@ -72,19 +71,19 @@ public: const exploded_node *m_enode; const supernode *m_snode; const gimple *m_stmt; - stmt_finder *m_stmt_finder; + std::unique_ptr<stmt_finder> m_stmt_finder; tree m_var; const svalue *m_sval; state_machine::state_t m_state; - pending_diagnostic *m_d; // owned + std::unique_ptr<pending_diagnostic> m_d; const exploded_edge *m_trailing_eedge; private: DISABLE_COPY_AND_ASSIGN (saved_diagnostic); unsigned m_idx; - exploded_path *m_best_epath; // owned - feasibility_problem *m_problem; // owned + std::unique_ptr<exploded_path> m_best_epath; + std::unique_ptr<feasibility_problem> m_problem; auto_vec<const saved_diagnostic *> m_duplicates; auto_delete_vec <pending_note> m_notes; @@ -113,18 +112,18 @@ public: bool add_diagnostic (const state_machine *sm, exploded_node *enode, const supernode *snode, const gimple *stmt, - stmt_finder *finder, + const stmt_finder *finder, tree var, const svalue *sval, state_machine::state_t state, - pending_diagnostic *d); + std::unique_ptr<pending_diagnostic> d); bool add_diagnostic (exploded_node *enode, const supernode *snode, const gimple *stmt, - stmt_finder *finder, - pending_diagnostic *d); + const stmt_finder *finder, + std::unique_ptr<pending_diagnostic> d); - void add_note (pending_note *pn); + void add_note (std::unique_ptr<pending_note> pn); void emit_saved_diagnostics (const exploded_graph &eg); diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 52978dd..9c32afc 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "fold-const.h" #include "gcc-rich-location.h" @@ -114,35 +115,29 @@ impl_region_model_context (program_state *state, } bool -impl_region_model_context::warn (pending_diagnostic *d) +impl_region_model_context::warn (std::unique_ptr<pending_diagnostic> d) { LOG_FUNC (get_logger ()); if (m_stmt == NULL && m_stmt_finder == NULL) { if (get_logger ()) get_logger ()->log ("rejecting diagnostic: no stmt"); - delete d; return false; } if (m_eg) return m_eg->get_diagnostic_manager ().add_diagnostic (m_enode_for_diag, m_enode_for_diag->get_supernode (), - m_stmt, m_stmt_finder, d); + m_stmt, m_stmt_finder, std::move (d)); else - { - delete d; - return false; - } + return false; } void -impl_region_model_context::add_note (pending_note *pn) +impl_region_model_context::add_note (std::unique_ptr<pending_note> pn) { LOG_FUNC (get_logger ()); if (m_eg) - m_eg->get_diagnostic_manager ().add_note (pn); - else - delete pn; + m_eg->get_diagnostic_manager ().add_note (std::move (pn)); } void @@ -198,12 +193,10 @@ impl_region_model_context::purge_state_involving (const svalue *sval) } void -impl_region_model_context::bifurcate (custom_edge_info *info) +impl_region_model_context::bifurcate (std::unique_ptr<custom_edge_info> info) { if (m_path_ctxt) - m_path_ctxt->bifurcate (info); - else - delete info; + m_path_ctxt->bifurcate (std::move (info)); } void @@ -287,7 +280,7 @@ public: const sm_state_map *old_smap, sm_state_map *new_smap, path_context *path_ctxt, - stmt_finder *stmt_finder = NULL, + const stmt_finder *stmt_finder = NULL, bool unknown_side_effects = false) : sm_context (sm_idx, sm), m_logger (eg.get_logger ()), @@ -401,10 +394,11 @@ public: } void warn (const supernode *snode, const gimple *stmt, - tree var, pending_diagnostic *d) final override + tree var, + std::unique_ptr<pending_diagnostic> d) final override { LOG_FUNC (get_logger ()); - gcc_assert (d); // take ownership + gcc_assert (d); impl_region_model_context old_ctxt (m_eg, m_enode_for_diag, m_old_state, m_new_state, NULL, NULL, NULL); @@ -416,14 +410,15 @@ public: : m_old_smap->get_global_state ()); m_eg.get_diagnostic_manager ().add_diagnostic (&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder, - var, var_old_sval, current, d); + var, var_old_sval, current, std::move (d)); } void warn (const supernode *snode, const gimple *stmt, - const svalue *sval, pending_diagnostic *d) final override + const svalue *sval, + std::unique_ptr<pending_diagnostic> d) final override { LOG_FUNC (get_logger ()); - gcc_assert (d); // take ownership + gcc_assert (d); impl_region_model_context old_ctxt (m_eg, m_enode_for_diag, m_old_state, m_new_state, NULL, NULL, NULL); @@ -433,7 +428,7 @@ public: : m_old_smap->get_global_state ()); m_eg.get_diagnostic_manager ().add_diagnostic (&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder, - NULL_TREE, sval, current, d); + NULL_TREE, sval, current, std::move (d)); } /* Hook for picking more readable trees for SSA names of temporaries, @@ -526,7 +521,7 @@ public: const sm_state_map *m_old_smap; sm_state_map *m_new_smap; path_context *m_path_ctxt; - stmt_finder *m_stmt_finder; + const stmt_finder *m_stmt_finder; /* Are we handling an external function with unknown side effects? */ bool m_unknown_side_effects; @@ -541,9 +536,9 @@ public: leak_stmt_finder (const exploded_graph &eg, tree var) : m_eg (eg), m_var (var) {} - stmt_finder *clone () const final override + std::unique_ptr<stmt_finder> clone () const final override { - return new leak_stmt_finder (m_eg, m_var); + return make_unique<leak_stmt_finder> (m_eg, m_var); } const gimple *find_stmt (const exploded_path &epath) @@ -864,12 +859,12 @@ impl_region_model_context::on_state_leak (const state_machine &sm, } tree leaked_tree_for_diag = fixup_tree_for_diagnostic (leaked_tree); - pending_diagnostic *pd = sm.on_leak (leaked_tree_for_diag); + std::unique_ptr<pending_diagnostic> pd = sm.on_leak (leaked_tree_for_diag); if (pd) m_eg->get_diagnostic_manager ().add_diagnostic (&sm, m_enode_for_diag, m_enode_for_diag->get_supernode (), m_stmt, &stmt_finder, - leaked_tree_for_diag, sval, state, pd); + leaked_tree_for_diag, sval, state, std::move (pd)); } /* Implementation of region_model_context::on_condition vfunc. @@ -1649,10 +1644,10 @@ exploded_node::replay_call_summary (exploded_graph &eg, call_summary_replay r (cd, called_fn, summary, ext_state); if (path_ctxt) - path_ctxt->bifurcate (new call_summary_edge_info (cd, - called_fn, - summary, - ext_state)); + path_ctxt->bifurcate (make_unique<call_summary_edge_info> (cd, + called_fn, + summary, + ext_state)); } @@ -1775,7 +1770,8 @@ public: src_point.get_fndecl (), src_stack_depth, "stack frame is popped here, invalidating saved environment"); - emission_path->add_event (m_stack_pop_event); + emission_path->add_event + (std::unique_ptr<custom_event> (m_stack_pop_event)); return false; } return false; @@ -1845,7 +1841,9 @@ exploded_node::on_longjmp (exploded_graph &eg, /* Verify that the setjmp's call_stack hasn't been popped. */ if (!valid_longjmp_stack_p (longjmp_point, setjmp_point)) { - ctxt->warn (new stale_jmp_buf (setjmp_call, longjmp_call, setjmp_point)); + ctxt->warn (make_unique<stale_jmp_buf> (setjmp_call, + longjmp_call, + setjmp_point)); return; } @@ -1879,7 +1877,7 @@ exploded_node::on_longjmp (exploded_graph &eg, { exploded_edge *eedge = eg.add_edge (const_cast<exploded_node *> (this), next, NULL, - new rewind_info_t (tmp_setjmp_record, longjmp_call)); + make_unique<rewind_info_t> (tmp_setjmp_record, longjmp_call)); /* For any diagnostics that were queued here (such as leaks) we want the checker_path to show the rewinding events after the "final event" @@ -2016,19 +2014,21 @@ dynamic_call_info_t::add_events_to_path (checker_path *emission_path, const int dest_stack_depth = dest_point.get_stack_depth (); if (m_is_returning_call) - emission_path->add_event (new return_event (eedge, - (m_dynamic_call - ? m_dynamic_call->location - : UNKNOWN_LOCATION), - dest_point.get_fndecl (), - dest_stack_depth)); + emission_path->add_event + (make_unique<return_event> (eedge, + (m_dynamic_call + ? m_dynamic_call->location + : UNKNOWN_LOCATION), + dest_point.get_fndecl (), + dest_stack_depth)); else - emission_path->add_event (new call_event (eedge, - (m_dynamic_call - ? m_dynamic_call->location - : UNKNOWN_LOCATION), - src_point.get_fndecl (), - src_stack_depth)); + emission_path->add_event + (make_unique<call_event> (eedge, + (m_dynamic_call + ? m_dynamic_call->location + : UNKNOWN_LOCATION), + src_point.get_fndecl (), + src_stack_depth)); } /* class rewind_info_t : public custom_edge_info. */ @@ -2073,12 +2073,12 @@ rewind_info_t::add_events_to_path (checker_path *emission_path, const int dst_stack_depth = dst_point.get_stack_depth (); emission_path->add_event - (new rewind_from_longjmp_event + (make_unique<rewind_from_longjmp_event> (&eedge, get_longjmp_call ()->location, src_point.get_fndecl (), src_stack_depth, this)); emission_path->add_event - (new rewind_to_setjmp_event + (make_unique<rewind_to_setjmp_event> (&eedge, get_setjmp_call ()->location, dst_point.get_fndecl (), dst_stack_depth, this)); @@ -2090,19 +2090,12 @@ rewind_info_t::add_events_to_path (checker_path *emission_path, exploded_edge::exploded_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, - custom_edge_info *custom_info) + std::unique_ptr<custom_edge_info> custom_info) : dedge<eg_traits> (src, dest), m_sedge (sedge), - m_custom_info (custom_info) + m_custom_info (std::move (custom_info)) { } -/* exploded_edge's dtor. */ - -exploded_edge::~exploded_edge () -{ - delete m_custom_info; -} - /* Implementation of dedge::dump_dot vfunc for exploded_edge. Use the label of the underlying superedge, if any. */ @@ -2674,7 +2667,7 @@ public: const exploded_edge &) const final override { emission_path->add_event - (new tainted_args_function_custom_event + (make_unique<tainted_args_function_custom_event> (DECL_SOURCE_LOCATION (m_fndecl), m_fndecl, 0)); } @@ -2710,12 +2703,12 @@ exploded_graph::add_function_entry (function *fun) program_state state (m_ext_state); state.push_frame (m_ext_state, fun); - custom_edge_info *edge_info = NULL; + std::unique_ptr<custom_edge_info> edge_info = NULL; if (lookup_attribute ("tainted_args", DECL_ATTRIBUTES (fun->decl))) { if (mark_params_as_tainted (&state, fun->decl, m_ext_state)) - edge_info = new tainted_args_function_info (fun->decl); + edge_info = make_unique<tainted_args_function_info> (fun->decl); } if (!state.m_valid) @@ -2723,12 +2716,9 @@ exploded_graph::add_function_entry (function *fun) exploded_node *enode = get_or_create_node (point, state, NULL); if (!enode) - { - delete edge_info; - return NULL; - } + return NULL; - add_edge (m_origin, enode, NULL, edge_info); + add_edge (m_origin, enode, NULL, std::move (edge_info)); m_functions_with_enodes.add (fun); @@ -2926,18 +2916,19 @@ exploded_graph::get_or_create_node (const program_point &point, /* Add an exploded_edge from SRC to DEST, recording its association with SEDGE (which may be NULL), and, if non-NULL, taking ownership - of REWIND_INFO. + of CUSTOM_INFO. Return the newly-created eedge. */ exploded_edge * exploded_graph::add_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, - custom_edge_info *custom_info) + std::unique_ptr<custom_edge_info> custom_info) { if (get_logger ()) get_logger ()->log ("creating edge EN: %i -> EN: %i", src->m_index, dest->m_index); - exploded_edge *e = new exploded_edge (src, dest, sedge, custom_info); + exploded_edge *e = new exploded_edge (src, dest, sedge, + std::move (custom_info)); digraph<eg_traits>::add_edge (e); return e; } @@ -3121,14 +3112,15 @@ public: /* Show the field in the struct declaration, e.g. "(1) field 'store' is marked with '__attribute__((tainted_args))'" */ emission_path->add_event - (new tainted_args_field_custom_event (m_field)); + (make_unique<tainted_args_field_custom_event> (m_field)); /* Show the callback in the initializer e.g. "(2) function 'gadget_dev_desc_UDC_store' used as initializer for field 'store' marked with '__attribute__((tainted_args))'". */ emission_path->add_event - (new tainted_args_callback_custom_event (m_loc, m_fndecl, 0, m_field)); + (make_unique<tainted_args_callback_custom_event> (m_loc, m_fndecl, + 0, m_field)); } private: @@ -3184,9 +3176,8 @@ add_tainted_args_callback (exploded_graph *eg, tree field, tree fndecl, } } - tainted_args_call_info *info - = new tainted_args_call_info (field, fndecl, loc); - eg->add_edge (eg->get_origin (), enode, NULL, info); + eg->add_edge (eg->get_origin (), enode, NULL, + make_unique<tainted_args_call_info> (field, fndecl, loc)); } /* Callback for walk_tree for finding callbacks within initializers; @@ -3783,7 +3774,7 @@ exploded_graph::maybe_create_dynamic_call (const gcall *call, node); if (enode) add_edge (node,enode, NULL, - new dynamic_call_info_t (call)); + make_unique<dynamic_call_info_t> (call)); return true; } } @@ -3814,7 +3805,7 @@ public: } void - bifurcate (custom_edge_info *info) final override + bifurcate (std::unique_ptr<custom_edge_info> info) final override { if (m_state_at_bifurcation) /* Verify that the state at bifurcation is consistent when we @@ -3827,7 +3818,7 @@ public: = std::unique_ptr<program_state> (new program_state (*m_cur_state)); /* Take ownership of INFO. */ - m_custom_eedge_infos.safe_push (info); + m_custom_eedge_infos.safe_push (info.release ()); } void terminate_path () final override @@ -4109,8 +4100,10 @@ exploded_graph::process_node (exploded_node *node) instances. For example, to handle a "realloc" call, we might split into 3 states, for the "failure", "resizing in place", and "moving to a new buffer" cases. */ - for (auto edge_info : path_ctxt.get_custom_eedge_infos ()) + for (auto edge_info_iter : path_ctxt.get_custom_eedge_infos ()) { + /* Take ownership of the edge infos from the path_ctxt. */ + std::unique_ptr<custom_edge_info> edge_info (edge_info_iter); if (logger) { logger->start_log_line (); @@ -4137,18 +4130,12 @@ exploded_graph::process_node (exploded_node *node) exploded_node *next2 = get_or_create_node (next_point, bifurcated_new_state, node); if (next2) - { - /* Take ownership of edge_info. */ - add_edge (node, next2, NULL, edge_info); - } - else - delete edge_info; + add_edge (node, next2, NULL, std::move (edge_info)); } else { if (logger) logger->log ("infeasible state, not adding node"); - delete edge_info; } } } @@ -4243,7 +4230,7 @@ exploded_graph::process_node (exploded_node *node) const svalue *fn_ptr_sval = model->get_rvalue (fn_ptr, &ctxt); if (fn_ptr_sval->all_zeroes_p ()) - ctxt.warn (new jump_through_null (call)); + ctxt.warn (make_unique<jump_through_null> (call)); } /* An unknown function or a special function was called @@ -4304,7 +4291,7 @@ exploded_graph::process_node (exploded_node *node) node); if (enode) add_edge (node, enode, NULL, - new dynamic_call_info_t (call, true)); + make_unique<dynamic_call_info_t> (call, true)); } } } @@ -4614,8 +4601,9 @@ exploded_path::get_final_enode () const feasibility_problem to *OUT. */ bool -exploded_path::feasible_p (logger *logger, feasibility_problem **out, - engine *eng, const exploded_graph *eg) const +exploded_path::feasible_p (logger *logger, + std::unique_ptr<feasibility_problem> *out, + engine *eng, const exploded_graph *eg) const { LOG_SCOPE (logger); @@ -4642,8 +4630,8 @@ exploded_path::feasible_p (logger *logger, feasibility_problem **out, const program_point &src_point = src_enode.get_point (); const gimple *last_stmt = src_point.get_supernode ()->get_last_stmt (); - *out = new feasibility_problem (edge_idx, *eedge, - last_stmt, rc); + *out = make_unique<feasibility_problem> (edge_idx, *eedge, + last_stmt, rc); } else delete rc; @@ -5965,17 +5953,17 @@ public: m_logger (logger) {} - void register_state_machine (state_machine *sm) final override + void register_state_machine (std::unique_ptr<state_machine> sm) final override { LOG_SCOPE (m_logger); - m_checkers->safe_push (sm); + m_checkers->safe_push (sm.release ()); } void register_known_function (const char *name, - known_function *kf) final override + std::unique_ptr<known_function> kf) final override { LOG_SCOPE (m_logger); - m_known_fn_mgr->add (name, kf); + m_known_fn_mgr->add (name, std::move (kf)); } logger *get_logger () const final override diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h index 5996252..8e3c160 100644 --- a/gcc/analyzer/exploded-graph.h +++ b/gcc/analyzer/exploded-graph.h @@ -56,8 +56,8 @@ class impl_region_model_context : public region_model_context uncertainty_t *uncertainty, logger *logger = NULL); - bool warn (pending_diagnostic *d) final override; - void add_note (pending_note *pn) final override; + bool warn (std::unique_ptr<pending_diagnostic> d) final override; + void add_note (std::unique_ptr<pending_note> pn) final override; void on_svalue_leak (const svalue *) override; void on_liveness_change (const svalue_set &live_svalues, const region_model *model) final override; @@ -90,7 +90,7 @@ class impl_region_model_context : public region_model_context void purge_state_involving (const svalue *sval) final override; - void bifurcate (custom_edge_info *info) final override; + void bifurcate (std::unique_ptr<custom_edge_info> info) final override; void terminate_path () final override; const extrinsic_state *get_ext_state () const final override { @@ -367,8 +367,7 @@ class exploded_edge : public dedge<eg_traits> public: exploded_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, - custom_edge_info *custom_info); - ~exploded_edge (); + std::unique_ptr<custom_edge_info> custom_info); void dump_dot (graphviz_out *gv, const dump_args_t &args) const final override; void dump_dot_label (pretty_printer *pp) const; @@ -380,10 +379,8 @@ class exploded_edge : public dedge<eg_traits> /* NULL for most edges; will be non-NULL for special cases such as an unwind from a longjmp to a setjmp, or when - a signal is delivered to a signal-handler. - - Owned by this class. */ - custom_edge_info *m_custom_info; + a signal is delivered to a signal-handler. */ + std::unique_ptr<custom_edge_info> m_custom_info; private: DISABLE_COPY_AND_ASSIGN (exploded_edge); @@ -801,7 +798,7 @@ public: exploded_node *enode_for_diag); exploded_edge *add_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, - custom_edge_info *custom = NULL); + std::unique_ptr<custom_edge_info> custom = NULL); per_program_point_data * get_or_create_per_program_point_data (const program_point &); @@ -926,7 +923,7 @@ public: void dump_to_file (const char *filename, const extrinsic_state &ext_state) const; - bool feasible_p (logger *logger, feasibility_problem **out, + bool feasible_p (logger *logger, std::unique_ptr<feasibility_problem> *out, engine *eng, const exploded_graph *eg) const; auto_vec<const exploded_edge *> m_edges; @@ -991,7 +988,7 @@ class stmt_finder { public: virtual ~stmt_finder () {} - virtual stmt_finder *clone () const = 0; + virtual std::unique_ptr<stmt_finder> clone () const = 0; virtual const gimple *find_stmt (const exploded_path &epath) = 0; }; diff --git a/gcc/analyzer/feasible-graph.cc b/gcc/analyzer/feasible-graph.cc index a946e4c..7c3dcf8 100644 --- a/gcc/analyzer/feasible-graph.cc +++ b/gcc/analyzer/feasible-graph.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -189,10 +190,10 @@ feasible_graph::add_feasibility_problem (feasible_node *src_fnode, /* Make an exploded_path from the origin to FNODE's exploded_node, following the edges in the feasible_graph. */ -exploded_path * +std::unique_ptr<exploded_path> feasible_graph::make_epath (feasible_node *fnode) const { - exploded_path *epath = new exploded_path (); + std::unique_ptr<exploded_path> epath (new exploded_path ()); /* FG is actually a tree. Built the path backwards, by walking backwards from FNODE until we reach the origin. */ diff --git a/gcc/analyzer/feasible-graph.h b/gcc/analyzer/feasible-graph.h index 2530119..9f37b08 100644 --- a/gcc/analyzer/feasible-graph.h +++ b/gcc/analyzer/feasible-graph.h @@ -195,7 +195,7 @@ class feasible_graph : public digraph <fg_traits> const exploded_edge *eedge, rejected_constraint *rc); - exploded_path *make_epath (feasible_node *fnode) const; + std::unique_ptr<exploded_path> make_epath (feasible_node *fnode) const; void dump_feasible_path (const feasible_node &dst_fnode, const char *filename) const; diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc index 48fb005..7341b06 100644 --- a/gcc/analyzer/known-function-manager.cc +++ b/gcc/analyzer/known-function-manager.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -47,11 +48,12 @@ known_function_manager::~known_function_manager () } void -known_function_manager::add (const char *name, known_function *kf) +known_function_manager::add (const char *name, + std::unique_ptr<known_function> kf) { LOG_FUNC_1 (get_logger (), "registering %s", name); tree id = get_identifier (name); - m_map_id_to_kf.put (id, kf); + m_map_id_to_kf.put (id, kf.release ()); } const known_function * diff --git a/gcc/analyzer/known-function-manager.h b/gcc/analyzer/known-function-manager.h index 2b95b7e..daf1bc5 100644 --- a/gcc/analyzer/known-function-manager.h +++ b/gcc/analyzer/known-function-manager.h @@ -30,7 +30,7 @@ class known_function_manager : public log_user public: known_function_manager (logger *logger); ~known_function_manager (); - void add (const char *name, known_function *kf); + void add (const char *name, std::unique_ptr<known_function> kf); const known_function *get_by_identifier (tree identifier); const known_function *get_by_fndecl (tree fndecl); diff --git a/gcc/analyzer/pending-diagnostic.cc b/gcc/analyzer/pending-diagnostic.cc index 50a8afc..fdbe615 100644 --- a/gcc/analyzer/pending-diagnostic.cc +++ b/gcc/analyzer/pending-diagnostic.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -49,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/exploded-graph.h" #include "diagnostic-path.h" #include "analyzer/checker-path.h" +#include "make-unique.h" #if ENABLE_ANALYZER @@ -177,12 +179,12 @@ pending_diagnostic::add_call_event (const exploded_edge &eedge, const int src_stack_depth = src_point.get_stack_depth (); const gimple *last_stmt = src_point.get_supernode ()->get_last_stmt (); emission_path->add_event - (new call_event (eedge, - (last_stmt - ? last_stmt->location - : UNKNOWN_LOCATION), - src_point.get_fndecl (), - src_stack_depth)); + (make_unique<call_event> (eedge, + (last_stmt + ? last_stmt->location + : UNKNOWN_LOCATION), + src_point.get_fndecl (), + src_stack_depth)); } } // namespace ana diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h index 4ea469e..6ca8ab9 100644 --- a/gcc/analyzer/pending-diagnostic.h +++ b/gcc/analyzer/pending-diagnostic.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_ANALYZER_PENDING_DIAGNOSTIC_H #include "diagnostic-path.h" +#include "analyzer/sm.h" namespace ana { diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc index cfa4dda..23635a1 100644 --- a/gcc/analyzer/program-point.cc +++ b/gcc/analyzer/program-point.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index 7537dc0..d00fd5e 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/region-model-asm.cc b/gcc/analyzer/region-model-asm.cc index b4c1f91..171b249 100644 --- a/gcc/analyzer/region-model-asm.cc +++ b/gcc/analyzer/region-model-asm.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 52c4205..30fa765 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -54,6 +55,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-path.h" #include "analyzer/pending-diagnostic.h" #include "gimple-pretty-print.h" +#include "make-unique.h" #if ENABLE_ANALYZER @@ -627,8 +629,8 @@ region_model::impl_call_pipe (const call_details &cd) /* Body of region_model::impl_call_pipe. */ if (cd.get_ctxt ()) { - cd.get_ctxt ()->bifurcate (new failure (cd)); - cd.get_ctxt ()->bifurcate (new success (cd)); + cd.get_ctxt ()->bifurcate (make_unique<failure> (cd)); + cd.get_ctxt ()->bifurcate (make_unique<success> (cd)); cd.get_ctxt ()->terminate_path (); } } @@ -745,7 +747,7 @@ region_model::impl_call_putenv (const call_details &cd) break; case MEMSPACE_STACK: if (ctxt) - ctxt->warn (new putenv_of_auto_var (fndecl, reg)); + ctxt->warn (make_unique<putenv_of_auto_var> (fndecl, reg)); break; } } @@ -1004,9 +1006,9 @@ region_model::impl_call_realloc (const call_details &cd) if (cd.get_ctxt ()) { - cd.get_ctxt ()->bifurcate (new failure (cd)); - cd.get_ctxt ()->bifurcate (new success_no_move (cd)); - cd.get_ctxt ()->bifurcate (new success_with_move (cd)); + cd.get_ctxt ()->bifurcate (make_unique<failure> (cd)); + cd.get_ctxt ()->bifurcate (make_unique<success_no_move> (cd)); + cd.get_ctxt ()->bifurcate (make_unique<success_with_move> (cd)); cd.get_ctxt ()->terminate_path (); } } @@ -1075,7 +1077,7 @@ region_model::impl_call_strchr (const call_details &cd) /* Bifurcate state, creating a "not found" out-edge. */ if (cd.get_ctxt ()) - cd.get_ctxt ()->bifurcate (new strchr_call_info (cd, false)); + cd.get_ctxt ()->bifurcate (make_unique<strchr_call_info> (cd, false)); /* The "unbifurcated" state is the "found" case. */ strchr_call_info found (cd, true); diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index f5999e6..de01627 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc index be1372c..6d2711a 100644 --- a/gcc/analyzer/region-model-reachability.cc +++ b/gcc/analyzer/region-model-reachability.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 7c44fc9..edf3412 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -813,14 +814,17 @@ region_model::get_gassign_result (const gassign *assign, if (TREE_CODE (rhs2_cst) == INTEGER_CST) { if (tree_int_cst_sgn (rhs2_cst) < 0) - ctxt->warn (new shift_count_negative_diagnostic - (assign, rhs2_cst)); + ctxt->warn + (make_unique<shift_count_negative_diagnostic> + (assign, rhs2_cst)); else if (compare_tree_int (rhs2_cst, TYPE_PRECISION (TREE_TYPE (rhs1))) >= 0) - ctxt->warn (new shift_count_overflow_diagnostic - (assign, TYPE_PRECISION (TREE_TYPE (rhs1)), - rhs2_cst)); + ctxt->warn + (make_unique<shift_count_overflow_diagnostic> + (assign, + int (TYPE_PRECISION (TREE_TYPE (rhs1))), + rhs2_cst)); } } @@ -1038,8 +1042,9 @@ region_model::check_for_poison (const svalue *sval, const region *src_region = NULL; if (pkind == POISON_KIND_UNINIT) src_region = get_region_for_poisoned_expr (expr); - if (ctxt->warn (new poisoned_value_diagnostic (diag_arg, pkind, - src_region))) + if (ctxt->warn (make_unique<poisoned_value_diagnostic> (diag_arg, + pkind, + src_region))) { /* We only want to report use of a poisoned value at the first place it gets used; return an unknown value to avoid generating @@ -1228,7 +1233,7 @@ region_model::on_stmt_pre (const gimple *stmt, { /* Handle the builtin "__analyzer_dump_path" by queuing a diagnostic at this exploded_node. */ - ctxt->warn (new dump_path_diagnostic ()); + ctxt->warn (make_unique<dump_path_diagnostic> ()); } else if (is_special_named_call_p (call, "__analyzer_dump_region_model", 0)) @@ -1784,16 +1789,18 @@ void region_model::check_symbolic_bounds (const region *base_reg, gcc_unreachable (); break; case DIR_READ: - ctxt->warn (new symbolic_buffer_overread (base_reg, diag_arg, - offset_tree, - num_bytes_tree, - capacity_tree)); + ctxt->warn (make_unique<symbolic_buffer_overread> (base_reg, + diag_arg, + offset_tree, + num_bytes_tree, + capacity_tree)); break; case DIR_WRITE: - ctxt->warn (new symbolic_buffer_overflow (base_reg, diag_arg, - offset_tree, - num_bytes_tree, - capacity_tree)); + ctxt->warn (make_unique<symbolic_buffer_overflow> (base_reg, + diag_arg, + offset_tree, + num_bytes_tree, + capacity_tree)); break; } } @@ -1884,10 +1891,10 @@ region_model::check_region_bounds (const region *reg, gcc_unreachable (); break; case DIR_READ: - ctxt->warn (new buffer_underread (reg, diag_arg, out)); + ctxt->warn (make_unique<buffer_underread> (reg, diag_arg, out)); break; case DIR_WRITE: - ctxt->warn (new buffer_underflow (reg, diag_arg, out)); + ctxt->warn (make_unique<buffer_underflow> (reg, diag_arg, out)); break; } } @@ -1912,10 +1919,12 @@ region_model::check_region_bounds (const region *reg, gcc_unreachable (); break; case DIR_READ: - ctxt->warn (new buffer_overread (reg, diag_arg, out, byte_bound)); + ctxt->warn (make_unique<buffer_overread> (reg, diag_arg, + out, byte_bound)); break; case DIR_WRITE: - ctxt->warn (new buffer_overflow (reg, diag_arg, out, byte_bound)); + ctxt->warn (make_unique<buffer_overflow> (reg, diag_arg, + out, byte_bound)); break; } } @@ -2315,8 +2324,8 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt, impl_call_memset (cd); return false; } - else if (is_named_call_p (callee_fndecl, "pipe", call, 1) - || is_named_call_p (callee_fndecl, "pipe2", call, 2)) + 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 @@ -2403,8 +2412,8 @@ region_model::on_call_post (const gcall *call, impl_call_operator_delete (cd); return; } - else if (is_named_call_p (callee_fndecl, "pipe", call, 1) - || is_named_call_p (callee_fndecl, "pipe2", call, 2)) + 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; @@ -2564,9 +2573,10 @@ check_external_function_for_access_attr (const gcall *call, m_access (access) { } - pending_note *make_note () final override + std::unique_ptr<pending_note> make_note () final override { - return new reason_attr_access (m_callee_fndecl, m_access); + return make_unique<reason_attr_access> + (m_callee_fndecl, m_access); } private: tree m_callee_fndecl; @@ -3374,7 +3384,8 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree ptr_tree, const poisoned_svalue *poisoned_sval = as_a <const poisoned_svalue *> (ptr_sval); enum poison_kind pkind = poisoned_sval->get_poison_kind (); - ctxt->warn (new poisoned_value_diagnostic (ptr, pkind, NULL)); + ctxt->warn (make_unique<poisoned_value_diagnostic> + (ptr, pkind, NULL)); } } } @@ -3531,14 +3542,16 @@ region_model::check_for_writable_region (const region* dest_reg, { const function_region *func_reg = as_a <const function_region *> (base_reg); tree fndecl = func_reg->get_fndecl (); - ctxt->warn (new write_to_const_diagnostic (func_reg, fndecl)); + ctxt->warn (make_unique<write_to_const_diagnostic> + (func_reg, fndecl)); } break; case RK_LABEL: { const label_region *label_reg = as_a <const label_region *> (base_reg); tree label = label_reg->get_label (); - ctxt->warn (new write_to_const_diagnostic (label_reg, label)); + ctxt->warn (make_unique<write_to_const_diagnostic> + (label_reg, label)); } break; case RK_DECL: @@ -3551,11 +3564,11 @@ region_model::check_for_writable_region (const region* dest_reg, "this" param is "T* const"). */ if (TREE_READONLY (decl) && is_global_var (decl)) - ctxt->warn (new write_to_const_diagnostic (dest_reg, decl)); + ctxt->warn (make_unique<write_to_const_diagnostic> (dest_reg, decl)); } break; case RK_STRING: - ctxt->warn (new write_to_string_literal_diagnostic (dest_reg)); + ctxt->warn (make_unique<write_to_string_literal_diagnostic> (dest_reg)); break; } } @@ -4031,8 +4044,8 @@ region_model::check_region_size (const region *lhs_reg, const svalue *rhs_sval, if (TREE_CODE (cst_cap) == INTEGER_CST && !capacity_compatible_with_type (cst_cap, pointee_size_tree, is_struct)) - ctxt->warn (new dubious_allocation_size (lhs_reg, rhs_reg, - cst_cap)); + ctxt->warn (make_unique <dubious_allocation_size> (lhs_reg, rhs_reg, + cst_cap)); } break; default: @@ -4043,8 +4056,9 @@ region_model::check_region_size (const region *lhs_reg, const svalue *rhs_sval, if (!v.get_result ()) { tree expr = get_representative_tree (capacity); - ctxt->warn (new dubious_allocation_size (lhs_reg, rhs_reg, - expr)); + ctxt->warn (make_unique <dubious_allocation_size> (lhs_reg, + rhs_reg, + expr)); } } break; @@ -5766,7 +5780,7 @@ region_model::check_dynamic_size_for_floats (const svalue *size_in_bytes, if (const svalue *float_sval = v.get_svalue_to_report ()) { tree diag_arg = get_representative_tree (float_sval); - ctxt->warn (new float_as_size_arg (diag_arg)); + ctxt->warn (make_unique<float_as_size_arg> (diag_arg)); } } @@ -6389,23 +6403,21 @@ region_model::maybe_complain_about_infoleak (const region *dst_reg, { /* Check for exposure. */ if (contains_uninit_p (copied_sval)) - ctxt->warn (new exposure_through_uninit_copy (src_reg, - dst_reg, - copied_sval)); + ctxt->warn (make_unique<exposure_through_uninit_copy> (src_reg, + dst_reg, + copied_sval)); } /* class noop_region_model_context : public region_model_context. */ void -noop_region_model_context::add_note (pending_note *pn) +noop_region_model_context::add_note (std::unique_ptr<pending_note>) { - delete pn; } void -noop_region_model_context::bifurcate (custom_edge_info *info) +noop_region_model_context::bifurcate (std::unique_ptr<custom_edge_info>) { - delete info; } void diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 19e8043..5c0bc44 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/region.h" #include "analyzer/known-function-manager.h" #include "analyzer/region-model-manager.h" +#include "analyzer/pending-diagnostic.h" using namespace ana; @@ -671,11 +672,11 @@ class region_model_context public: /* Hook for clients to store pending diagnostics. Return true if the diagnostic was stored, or false if it was deleted. */ - virtual bool warn (pending_diagnostic *d) = 0; + virtual bool warn (std::unique_ptr<pending_diagnostic> d) = 0; - /* Hook for clients to add a note to the last previously stored pending diagnostic. - Takes ownership of the pending_node (or deletes it). */ - virtual void add_note (pending_note *pn) = 0; + /* Hook for clients to add a note to the last previously stored + pending diagnostic. */ + virtual void add_note (std::unique_ptr<pending_note> pn) = 0; /* Hook for clients to be notified when an SVAL that was reachable in a previous state is no longer live, so that clients can emit warnings @@ -728,9 +729,8 @@ class region_model_context /* Hook for clients to purge state involving SVAL. */ virtual void purge_state_involving (const svalue *sval) = 0; - /* Hook for clients to split state with a non-standard path. - Take ownership of INFO. */ - virtual void bifurcate (custom_edge_info *info) = 0; + /* Hook for clients to split state with a non-standard path. */ + virtual void bifurcate (std::unique_ptr<custom_edge_info> info) = 0; /* Hook for clients to terminate the standard path. */ virtual void terminate_path () = 0; @@ -774,8 +774,8 @@ class region_model_context class noop_region_model_context : public region_model_context { public: - bool warn (pending_diagnostic *) override { return false; } - void add_note (pending_note *pn) override; + bool warn (std::unique_ptr<pending_diagnostic>) override { return false; } + void add_note (std::unique_ptr<pending_note>) override; void on_svalue_leak (const svalue *) override {} void on_liveness_change (const svalue_set &, const region_model *) override {} @@ -805,7 +805,7 @@ public: void purge_state_involving (const svalue *sval ATTRIBUTE_UNUSED) override {} - void bifurcate (custom_edge_info *info) override; + void bifurcate (std::unique_ptr<custom_edge_info> info) override; void terminate_path () override; const extrinsic_state *get_ext_state () const override { return NULL; } @@ -847,14 +847,14 @@ private: class region_model_context_decorator : public region_model_context { public: - bool warn (pending_diagnostic *d) override + bool warn (std::unique_ptr<pending_diagnostic> d) override { - return m_inner->warn (d); + return m_inner->warn (std::move (d)); } - void add_note (pending_note *pn) override + void add_note (std::unique_ptr<pending_note> pn) override { - m_inner->add_note (pn); + m_inner->add_note (std::move (pn)); } void on_svalue_leak (const svalue *sval) override @@ -917,9 +917,9 @@ class region_model_context_decorator : public region_model_context m_inner->purge_state_involving (sval); } - void bifurcate (custom_edge_info *info) override + void bifurcate (std::unique_ptr<custom_edge_info> info) override { - m_inner->bifurcate (info); + m_inner->bifurcate (std::move (info)); } void terminate_path () override @@ -961,9 +961,9 @@ protected: class note_adding_context : public region_model_context_decorator { public: - bool warn (pending_diagnostic *d) override + bool warn (std::unique_ptr<pending_diagnostic> d) override { - if (m_inner->warn (d)) + if (m_inner->warn (std::move (d))) { add_note (make_note ()); return true; @@ -973,7 +973,7 @@ public: } /* Hook to make the new note. */ - virtual pending_note *make_note () = 0; + virtual std::unique_ptr<pending_note> make_note () = 0; protected: note_adding_context (region_model_context *inner) @@ -1116,9 +1116,9 @@ using namespace ::selftest; class test_region_model_context : public noop_region_model_context { public: - bool warn (pending_diagnostic *d) final override + bool warn (std::unique_ptr<pending_diagnostic> d) final override { - m_diagnostics.safe_push (d); + m_diagnostics.safe_push (d.release ()); return true; } diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index da5a13e..4bc1918 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc index ae846cd..da0e92b 100644 --- a/gcc/analyzer/sm-fd.cc +++ b/gcc/analyzer/sm-fd.cc @@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -110,7 +112,7 @@ public: const svalue *rhs) const final override; bool can_purge_p (state_t s) const final override; - pending_diagnostic *on_leak (tree var) const final override; + std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; bool is_unchecked_fd_p (state_t s) const; bool is_valid_fd_p (state_t s) const; @@ -885,9 +887,10 @@ fd_state_machine::check_for_fd_attrs ( { sm_ctxt->warn (node, stmt, arg, - new fd_use_after_close (*this, diag_arg, - callee_fndecl, attr_name, - arg_idx)); + make_unique<fd_use_after_close> + (*this, diag_arg, + callee_fndecl, attr_name, + arg_idx)); continue; } @@ -895,9 +898,10 @@ fd_state_machine::check_for_fd_attrs ( { if (!is_constant_fd_p (state)) sm_ctxt->warn (node, stmt, arg, - new fd_use_without_check (*this, diag_arg, - callee_fndecl, attr_name, - arg_idx)); + make_unique<fd_use_without_check> + (*this, diag_arg, + callee_fndecl, attr_name, + arg_idx)); } switch (fd_attr_access_dir) @@ -910,8 +914,11 @@ fd_state_machine::check_for_fd_attrs ( { sm_ctxt->warn ( node, stmt, arg, - new fd_access_mode_mismatch (*this, diag_arg, DIRS_WRITE, - callee_fndecl, attr_name, arg_idx)); + make_unique<fd_access_mode_mismatch> (*this, diag_arg, + DIRS_WRITE, + callee_fndecl, + attr_name, + arg_idx)); } break; @@ -921,8 +928,11 @@ fd_state_machine::check_for_fd_attrs ( { sm_ctxt->warn ( node, stmt, arg, - new fd_access_mode_mismatch (*this, diag_arg, DIRS_READ, - callee_fndecl, attr_name, arg_idx)); + make_unique<fd_access_mode_mismatch> (*this, diag_arg, + DIRS_READ, + callee_fndecl, + attr_name, + arg_idx)); } break; @@ -963,7 +973,8 @@ fd_state_machine::on_open (sm_context *sm_ctxt, const supernode *node, } else { - sm_ctxt->warn (node, stmt, NULL_TREE, new fd_leak (*this, NULL_TREE)); + sm_ctxt->warn (node, stmt, NULL_TREE, + make_unique<fd_leak> (*this, NULL_TREE)); } } @@ -975,7 +986,8 @@ fd_state_machine::on_creat (sm_context *sm_ctxt, const supernode *node, if (lhs) sm_ctxt->on_transition (node, stmt, lhs, m_start, m_unchecked_write_only); else - sm_ctxt->warn (node, stmt, NULL_TREE, new fd_leak (*this, NULL_TREE)); + sm_ctxt->warn (node, stmt, NULL_TREE, + make_unique<fd_leak> (*this, NULL_TREE)); } void @@ -1021,7 +1033,8 @@ fd_state_machine::check_for_dup (sm_context *sm_ctxt, const supernode *node, { sm_ctxt->warn ( node, stmt, arg_2, - new fd_use_without_check (*this, diag_arg_2, callee_fndecl)); + make_unique<fd_use_without_check> (*this, diag_arg_2, + callee_fndecl)); return; } /* dup2 returns value of its second argument on success.But, the @@ -1059,7 +1072,8 @@ fd_state_machine::on_close (sm_context *sm_ctxt, const supernode *node, if (is_closed_fd_p (state)) { - sm_ctxt->warn (node, stmt, arg, new fd_double_close (*this, diag_arg)); + sm_ctxt->warn (node, stmt, arg, + make_unique<fd_double_close> (*this, diag_arg)); sm_ctxt->set_next_state (stmt, arg, m_stop); } } @@ -1091,7 +1105,8 @@ fd_state_machine::check_for_open_fd ( if (is_closed_fd_p (state)) { sm_ctxt->warn (node, stmt, arg, - new fd_use_after_close (*this, diag_arg, callee_fndecl)); + make_unique<fd_use_after_close> (*this, diag_arg, + callee_fndecl)); } else @@ -1101,7 +1116,8 @@ fd_state_machine::check_for_open_fd ( if (!is_constant_fd_p (state)) sm_ctxt->warn ( node, stmt, arg, - new fd_use_without_check (*this, diag_arg, callee_fndecl)); + make_unique<fd_use_without_check> (*this, diag_arg, + callee_fndecl)); } switch (callee_fndecl_dir) { @@ -1112,7 +1128,7 @@ fd_state_machine::check_for_open_fd ( { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new fd_access_mode_mismatch ( + make_unique<fd_access_mode_mismatch> ( *this, diag_arg, DIRS_WRITE, callee_fndecl)); } @@ -1123,7 +1139,7 @@ fd_state_machine::check_for_open_fd ( { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new fd_access_mode_mismatch ( + make_unique<fd_access_mode_mismatch> ( *this, diag_arg, DIRS_READ, callee_fndecl)); } break; @@ -1195,10 +1211,10 @@ fd_state_machine::can_purge_p (state_t s) const return true; } -pending_diagnostic * +std::unique_ptr<pending_diagnostic> fd_state_machine::on_leak (tree var) const { - return new fd_leak (*this, var); + return make_unique<fd_leak> (*this, var); } } // namespace diff --git a/gcc/analyzer/sm-file.cc b/gcc/analyzer/sm-file.cc index 13f2507..cbd1788 100644 --- a/gcc/analyzer/sm-file.cc +++ b/gcc/analyzer/sm-file.cc @@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -79,7 +81,7 @@ public: const svalue *rhs) const final override; bool can_purge_p (state_t s) const final override; - pending_diagnostic *on_leak (tree var) const final override; + std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; /* State for a FILE * returned from fopen that hasn't been checked for NULL. @@ -404,7 +406,7 @@ fileptr_state_machine::on_stmt (sm_context *sm_ctxt, { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new double_fclose (*this, diag_arg)); + make_unique<double_fclose> (*this, diag_arg)); sm_ctxt->set_next_state (stmt, arg, m_stop); } return true; @@ -471,10 +473,10 @@ fileptr_state_machine::can_purge_p (state_t s) const fileptr_state_machine, for complaining about leaks of FILE * in state 'unchecked' and 'nonnull'. */ -pending_diagnostic * +std::unique_ptr<pending_diagnostic> fileptr_state_machine::on_leak (tree var) const { - return new file_leak (*this, var); + return make_unique<file_leak> (*this, var); } } // anonymous namespace diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index fef6e63..d050ef8 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -383,7 +385,7 @@ public: const svalue *rhs) const final override; bool can_purge_p (state_t s) const final override; - pending_diagnostic *on_leak (tree var) const final override; + std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; bool reset_when_passed_to_unknown_fn_p (state_t s, bool is_mutable) const final override; @@ -1726,9 +1728,8 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new possible_null_arg (*this, diag_arg, - callee_fndecl, - i)); + make_unique<possible_null_arg> + (*this, diag_arg, callee_fndecl, i)); const allocation_state *astate = as_a_allocation_state (state); sm_ctxt->set_next_state (stmt, arg, @@ -1738,8 +1739,8 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new null_arg (*this, diag_arg, - callee_fndecl, i)); + make_unique<null_arg> + (*this, diag_arg, callee_fndecl, i)); sm_ctxt->set_next_state (stmt, arg, m_stop); } } @@ -1781,7 +1782,8 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new possible_null_deref (*this, diag_arg)); + make_unique<possible_null_deref> (*this, + diag_arg)); const allocation_state *astate = as_a_allocation_state (state); sm_ctxt->set_next_state (stmt, arg, astate->get_nonnull ()); } @@ -1789,7 +1791,7 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new null_deref (*this, diag_arg)); + make_unique<null_deref> (*this, diag_arg)); sm_ctxt->set_next_state (stmt, arg, m_stop); } else if (freed_p (state)) @@ -1797,8 +1799,8 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); const allocation_state *astate = as_a_allocation_state (state); sm_ctxt->warn (node, stmt, arg, - new use_after_free (*this, diag_arg, - astate->m_deallocator)); + make_unique<use_after_free> + (*this, diag_arg, astate->m_deallocator)); sm_ctxt->set_next_state (stmt, arg, m_stop); } } @@ -1850,8 +1852,8 @@ malloc_state_machine::handle_free_of_non_heap (sm_context *sm_ctxt, freed_reg = old_model->deref_rvalue (ptr_sval, arg, NULL); } sm_ctxt->warn (node, call, arg, - new free_of_non_heap (*this, diag_arg, freed_reg, - d->m_name)); + make_unique<free_of_non_heap> + (*this, diag_arg, freed_reg, d->m_name)); sm_ctxt->set_next_state (call, arg, m_stop); } @@ -1879,11 +1881,11 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt, { /* Wrong allocator. */ tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); - pending_diagnostic *pd - = new mismatching_deallocation (*this, diag_arg, - astate->m_deallocators, - d); - sm_ctxt->warn (node, call, arg, pd); + sm_ctxt->warn (node, call, arg, + make_unique<mismatching_deallocation> + (*this, diag_arg, + astate->m_deallocators, + d)); } sm_ctxt->set_next_state (call, arg, d->m_freed); } @@ -1895,7 +1897,7 @@ malloc_state_machine::on_deallocator_call (sm_context *sm_ctxt, /* freed -> stop, with warning. */ tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, call, arg, - new double_free (*this, diag_arg, d->m_name)); + make_unique<double_free> (*this, diag_arg, d->m_name)); sm_ctxt->set_next_state (call, arg, m_stop); } else if (state == m_non_heap) @@ -1933,11 +1935,10 @@ malloc_state_machine::on_realloc_call (sm_context *sm_ctxt, { /* Wrong allocator. */ tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); - pending_diagnostic *pd - = new mismatching_deallocation (*this, diag_arg, - astate->m_deallocators, - d); - sm_ctxt->warn (node, call, arg, pd); + sm_ctxt->warn (node, call, arg, + make_unique<mismatching_deallocation> + (*this, diag_arg, + astate->m_deallocators, d)); sm_ctxt->set_next_state (call, arg, m_stop); if (path_context *path_ctxt = sm_ctxt->get_path_context ()) path_ctxt->terminate_path (); @@ -1948,7 +1949,7 @@ malloc_state_machine::on_realloc_call (sm_context *sm_ctxt, /* freed -> stop, with warning. */ tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, call, arg, - new double_free (*this, diag_arg, "free")); + make_unique<double_free> (*this, diag_arg, "free")); sm_ctxt->set_next_state (call, arg, m_stop); if (path_context *path_ctxt = sm_ctxt->get_path_context ()) path_ctxt->terminate_path (); @@ -2030,10 +2031,10 @@ malloc_state_machine::can_purge_p (state_t s) const (for complaining about leaks of pointers in state 'unchecked' and 'nonnull'). */ -pending_diagnostic * +std::unique_ptr<pending_diagnostic> malloc_state_machine::on_leak (tree var) const { - return new malloc_leak (*this, var); + return make_unique<malloc_leak> (*this, var); } /* Implementation of state_machine::reset_when_passed_to_unknown_fn_p vfunc diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc index 3208132..704f628 100644 --- a/gcc/analyzer/sm-pattern-test.cc +++ b/gcc/analyzer/sm-pattern-test.cc @@ -21,8 +21,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -139,8 +141,8 @@ pattern_test_state_machine::on_condition (sm_context *sm_ctxt, if (tree lhs_expr = sm_ctxt->get_diagnostic_tree (lhs)) { - pending_diagnostic *diag = new pattern_match (lhs_expr, op, rhs_cst); - sm_ctxt->warn (node, stmt, lhs_expr, diag); + sm_ctxt->warn (node, stmt, lhs_expr, + make_unique<pattern_match> (lhs_expr, op, rhs_cst)); } } diff --git a/gcc/analyzer/sm-sensitive.cc b/gcc/analyzer/sm-sensitive.cc index cb5f859..d19765f 100644 --- a/gcc/analyzer/sm-sensitive.cc +++ b/gcc/analyzer/sm-sensitive.cc @@ -20,8 +20,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -181,7 +183,8 @@ sensitive_state_machine::warn_for_any_exposure (sm_context *sm_ctxt, { tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); sm_ctxt->warn (node, stmt, arg, - new exposure_through_output_file (*this, diag_arg)); + make_unique<exposure_through_output_file> (*this, + diag_arg)); } } diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc index e3b08c3..87e21a4 100644 --- a/gcc/analyzer/sm-signal.cc +++ b/gcc/analyzer/sm-signal.cc @@ -21,8 +21,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -232,7 +234,7 @@ public: const final override { emission_path->add_event - (new precanned_custom_event + (make_unique<precanned_custom_event> (UNKNOWN_LOCATION, NULL_TREE, 0, "later on," " when the signal is delivered to the process")); @@ -277,7 +279,7 @@ public: src_enode); if (dst_enode) eg->add_edge (src_enode, dst_enode, NULL, /*state_change (),*/ - new signal_delivery_edge_info_t ()); + make_unique<signal_delivery_edge_info_t> ()); } const signal_state_machine &m_sm; @@ -351,8 +353,8 @@ signal_state_machine::on_stmt (sm_context *sm_ctxt, if (signal_unsafe_p (callee_fndecl)) if (sm_ctxt->get_global_state () == m_in_signal_handler) sm_ctxt->warn (node, stmt, NULL_TREE, - new signal_unsafe_call (*this, call, - callee_fndecl)); + make_unique<signal_unsafe_call> + (*this, call, callee_fndecl)); } return false; diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index bc27533..d4ee6c4 100644 --- a/gcc/analyzer/sm-taint.cc +++ b/gcc/analyzer/sm-taint.cc @@ -21,8 +21,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -1163,10 +1165,11 @@ taint_state_machine::check_for_tainted_size_arg (sm_context *sm_ctxt, TREE_STRING_POINTER (access->to_external_string ()); tree diag_size = sm_ctxt->get_diagnostic_tree (size_arg); sm_ctxt->warn (node, call, size_arg, - new tainted_access_attrib_size (*this, diag_size, b, - callee_fndecl, - access->sizarg, - access_str)); + make_unique<tainted_access_attrib_size> + (*this, diag_size, b, + callee_fndecl, + access->sizarg, + access_str)); } } } @@ -1201,7 +1204,7 @@ taint_state_machine::check_for_tainted_divisor (sm_context *sm_ctxt, tree diag_divisor = sm_ctxt->get_diagnostic_tree (divisor_expr); sm_ctxt->warn (node, assign, divisor_expr, - new tainted_divisor (*this, diag_divisor, b)); + make_unique <tainted_divisor> (*this, diag_divisor, b)); sm_ctxt->set_next_state (assign, divisor_sval, m_stop); } } @@ -1264,7 +1267,7 @@ region_model::check_region_for_taint (const region *reg, if (taint_sm.get_taint (state, index->get_type (), &b)) { tree arg = get_representative_tree (index); - ctxt->warn (new tainted_array_index (taint_sm, arg, b)); + ctxt->warn (make_unique<tainted_array_index> (taint_sm, arg, b)); } } break; @@ -1286,7 +1289,7 @@ region_model::check_region_for_taint (const region *reg, if (taint_sm.get_taint (state, effective_type, &b)) { tree arg = get_representative_tree (offset); - ctxt->warn (new tainted_offset (taint_sm, arg, b)); + ctxt->warn (make_unique<tainted_offset> (taint_sm, arg, b)); } } break; @@ -1311,7 +1314,7 @@ region_model::check_region_for_taint (const region *reg, if (taint_sm.get_taint (state, size_sval->get_type (), &b)) { tree arg = get_representative_tree (size_sval); - ctxt->warn (new tainted_size (taint_sm, arg, b)); + ctxt->warn (make_unique<tainted_size> (taint_sm, arg, b)); } } break; @@ -1357,7 +1360,8 @@ region_model::check_dynamic_size_for_taint (enum memory_space mem_space, if (taint_sm.get_taint (state, size_in_bytes->get_type (), &b)) { tree arg = get_representative_tree (size_in_bytes); - ctxt->warn (new tainted_allocation_size (taint_sm, arg, b, mem_space)); + ctxt->warn (make_unique<tainted_allocation_size> + (taint_sm, arg, b, mem_space)); } } diff --git a/gcc/analyzer/sm.cc b/gcc/analyzer/sm.cc index 1ab4c21..1f329cb 100644 --- a/gcc/analyzer/sm.cc +++ b/gcc/analyzer/sm.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" @@ -39,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "analyzer/store.h" #include "analyzer/svalue.h" #include "analyzer/program-state.h" +#include "analyzer/pending-diagnostic.h" #if ENABLE_ANALYZER @@ -121,6 +123,14 @@ state_machine::get_state_by_name (const char *name) const gcc_unreachable (); } +/* Base implementation of state_machine::on_leak. */ + +std::unique_ptr<pending_diagnostic> +state_machine::on_leak (tree var ATTRIBUTE_UNUSED) const +{ + return NULL; +} + /* Dump a multiline representation of this state machine to PP. */ void diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h index 87ab11c..0171474 100644 --- a/gcc/analyzer/sm.h +++ b/gcc/analyzer/sm.h @@ -123,10 +123,8 @@ public: virtual bool can_purge_p (state_t s) const = 0; /* Called when VAR leaks (and !can_purge_p). */ - virtual pending_diagnostic *on_leak (tree var ATTRIBUTE_UNUSED) const - { - return NULL; - } + virtual std::unique_ptr<pending_diagnostic> + on_leak (tree var ATTRIBUTE_UNUSED) const; /* Return true if S should be reset to "start" for values passed (or reachable from) calls to unknown functions. IS_MUTABLE is true for pointers as @@ -250,9 +248,11 @@ public: /* Called by state_machine in response to pattern matches: issue a diagnostic D using NODE and STMT for location information. */ virtual void warn (const supernode *node, const gimple *stmt, - tree var, pending_diagnostic *d) = 0; + tree var, + std::unique_ptr<pending_diagnostic> d) = 0; virtual void warn (const supernode *node, const gimple *stmt, - const svalue *var, pending_diagnostic *d) = 0; + const svalue *var, + std::unique_ptr<pending_diagnostic> d) = 0; /* For use when generating trees when creating pending_diagnostics, so that rather than e.g. diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc index d3f516a..6fac18a 100644 --- a/gcc/analyzer/state-purge.cc +++ b/gcc/analyzer/state-purge.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 2631ea2..c0f5ed1 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc index 0e9a325..8195fe8 100644 --- a/gcc/analyzer/supergraph.cc +++ b/gcc/analyzer/supergraph.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc index 4b00a81..aa03b04 100644 --- a/gcc/analyzer/svalue.cc +++ b/gcc/analyzer/svalue.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/trimmed-graph.cc b/gcc/analyzer/trimmed-graph.cc index 9fdb4a9..9a42248 100644 --- a/gcc/analyzer/trimmed-graph.cc +++ b/gcc/analyzer/trimmed-graph.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "tree.h" diff --git a/gcc/analyzer/varargs.cc b/gcc/analyzer/varargs.cc index e4dbad7..f7d4838 100644 --- a/gcc/analyzer/varargs.cc +++ b/gcc/analyzer/varargs.cc @@ -19,8 +19,10 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" +#include "make-unique.h" #include "tree.h" #include "function.h" #include "basic-block.h" @@ -212,7 +214,7 @@ public: { return s != m_started; } - pending_diagnostic *on_leak (tree var) const final override; + std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override; /* State for a va_list that the result of a va_start or va_copy. */ state_t m_started; @@ -553,8 +555,8 @@ va_list_state_machine::check_for_ended_va_list (sm_context *sm_ctxt, { if (sm_ctxt->get_state (call, arg) == m_ended) sm_ctxt->warn (node, call, arg, - new va_list_use_after_va_end (*this, arg, NULL_TREE, - usage_fnname)); + make_unique<va_list_use_after_va_end> + (*this, arg, NULL_TREE, usage_fnname)); } /* Get the svalue with associated va_list_state_machine state for @@ -629,10 +631,10 @@ va_list_state_machine::on_va_end (sm_context *sm_ctxt, /* Implementation of state_machine::on_leak vfunc for va_list_state_machine (for complaining about leaks of values in state 'started'). */ -pending_diagnostic * +std::unique_ptr<pending_diagnostic> va_list_state_machine::on_leak (tree var) const { - return new va_list_leak (*this, NULL, var); + return make_unique<va_list_leak> (*this, NULL, var); } } // anonymous namespace @@ -786,13 +788,13 @@ public: = get_num_variadic_arguments (dst_node->get_function ()->decl, call_stmt); emission_path->add_event - (new va_arg_call_event (eedge, - (last_stmt - ? last_stmt->location - : UNKNOWN_LOCATION), - src_point.get_fndecl (), - src_stack_depth, - num_variadic_arguments)); + (make_unique<va_arg_call_event> (eedge, + (last_stmt + ? last_stmt->location + : UNKNOWN_LOCATION), + src_point.get_fndecl (), + src_stack_depth, + num_variadic_arguments)); } else pending_diagnostic::add_call_event (eedge, emission_path); @@ -1000,17 +1002,19 @@ region_model::impl_call_va_arg (const call_details &cd) else { if (ctxt) - ctxt->warn (new va_arg_type_mismatch (va_list_tree, - arg_reg, - lhs_type, - arg_type)); + ctxt->warn (make_unique <va_arg_type_mismatch> + (va_list_tree, + arg_reg, + lhs_type, + arg_type)); saw_problem = true; } } else { if (ctxt) - ctxt->warn (new va_list_exhausted (va_list_tree, arg_reg)); + ctxt->warn (make_unique <va_list_exhausted> (va_list_tree, + arg_reg)); saw_problem = true; } } |