aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/varargs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/analyzer/varargs.cc')
-rw-r--r--gcc/analyzer/varargs.cc57
1 files changed, 37 insertions, 20 deletions
diff --git a/gcc/analyzer/varargs.cc b/gcc/analyzer/varargs.cc
index 6ea0d29..4947271 100644
--- a/gcc/analyzer/varargs.cc
+++ b/gcc/analyzer/varargs.cc
@@ -205,7 +205,11 @@ public:
{
return s != m_started;
}
- std::unique_ptr<pending_diagnostic> on_leak (tree var) const final override;
+
+ std::unique_ptr<pending_diagnostic>
+ on_leak (tree var,
+ const program_state *old_state,
+ const program_state *new_state) const final override;
/* State for a va_list that is the result of a va_start or va_copy. */
state_t m_started;
@@ -294,15 +298,15 @@ get_stateful_arg (sm_context &sm_ctxt, const gcall &call, unsigned arg_idx)
if (const program_state *new_state = sm_ctxt.get_new_program_state ())
{
const region_model *new_model = new_state->m_region_model;
- const svalue *ptr_sval = new_model->get_rvalue (ap, NULL);
- const region *reg = new_model->deref_rvalue (ptr_sval, ap, NULL);
- const svalue *impl_sval = new_model->get_store_value (reg, NULL);
+ const svalue *ptr_sval = new_model->get_rvalue (ap, nullptr);
+ const region *reg = new_model->deref_rvalue (ptr_sval, ap, nullptr);
+ const svalue *impl_sval = new_model->get_store_value (reg, nullptr);
if (const svalue *cast = impl_sval->maybe_undo_cast ())
impl_sval = cast;
return impl_sval;
}
}
- return NULL;
+ return nullptr;
}
/* Abstract class for diagnostics relating to va_list_state_machine. */
@@ -335,11 +339,11 @@ public:
const final override
{
if (change.m_new_state == m_sm.m_started)
- return diagnostic_event::meaning (diagnostic_event::VERB_acquire,
- diagnostic_event::NOUN_resource);
+ return diagnostic_event::meaning (diagnostic_event::verb::acquire,
+ diagnostic_event::noun::resource);
if (change.m_new_state == m_sm.m_ended)
- return diagnostic_event::meaning (diagnostic_event::VERB_release,
- diagnostic_event::NOUN_resource);
+ return diagnostic_event::meaning (diagnostic_event::verb::release,
+ diagnostic_event::noun::resource);
return diagnostic_event::meaning ();
}
@@ -366,7 +370,7 @@ protected:
return "va_end";
}
}
- return NULL;
+ return nullptr;
}
const va_list_state_machine &m_sm;
@@ -460,10 +464,14 @@ class va_list_leak : public va_list_sm_diagnostic
{
public:
va_list_leak (const va_list_state_machine &sm,
- const svalue *ap_sval, tree ap_tree)
+ const svalue *ap_sval, tree ap_tree,
+ const program_state *final_state)
: va_list_sm_diagnostic (sm, ap_sval, ap_tree),
- m_start_event_fnname (NULL)
+ m_start_event_fnname (nullptr),
+ m_final_state ()
{
+ if (final_state)
+ m_final_state = std::make_unique<program_state> (*final_state);
}
int get_controlling_option () const final override
@@ -524,9 +532,16 @@ public:
return true;
}
+ const program_state *
+ get_final_state () const final override
+ {
+ return m_final_state.get ();
+ }
+
private:
diagnostic_event_id_t m_start_event;
const char *m_start_event_fnname;
+ std::unique_ptr<program_state> m_final_state;
};
/* Update state machine for a "va_start" call. */
@@ -562,7 +577,7 @@ va_list_state_machine::check_for_ended_va_list (sm_context &sm_ctxt,
/* Get the svalue with associated va_list_state_machine state for
ARG_IDX of CALL to va_copy, if SM_CTXT supports this,
- or NULL otherwise. */
+ or nullptr otherwise. */
static const svalue *
get_stateful_va_copy_arg (sm_context &sm_ctxt,
@@ -572,10 +587,10 @@ get_stateful_va_copy_arg (sm_context &sm_ctxt,
if (const program_state *new_state = sm_ctxt.get_new_program_state ())
{
const region_model *new_model = new_state->m_region_model;
- const svalue *arg = get_va_copy_arg (new_model, NULL, call, arg_idx);
+ const svalue *arg = get_va_copy_arg (new_model, nullptr, call, arg_idx);
return arg;
}
- return NULL;
+ return nullptr;
}
/* Update state machine for a "va_copy" call. */
@@ -633,9 +648,11 @@ va_list_state_machine::on_va_end (sm_context &sm_ctxt,
(for complaining about leaks of values in state 'started'). */
std::unique_ptr<pending_diagnostic>
-va_list_state_machine::on_leak (tree var) const
+va_list_state_machine::on_leak (tree var,
+ const program_state *,
+ const program_state *new_state) const
{
- return std::make_unique<va_list_leak> (*this, nullptr, var);
+ return std::make_unique<va_list_leak> (*this, nullptr, var, new_state);
}
} // anonymous namespace
@@ -723,7 +740,7 @@ kf_va_copy::impl_call_pre (const call_details &cd) const
in_va_list
= model->check_for_poison (in_va_list,
get_va_list_diag_arg (cd.get_arg_tree (1)),
- NULL,
+ nullptr,
cd.get_ctxt ());
const region *out_dst_reg
@@ -1003,14 +1020,14 @@ va_arg_compatible_types_p (tree lhs_type, tree arg_type, const svalue &arg_sval)
}
/* If AP_SVAL is a pointer to a var_arg_region, return that var_arg_region.
- Otherwise return NULL. */
+ Otherwise return nullptr. */
static const var_arg_region *
maybe_get_var_arg_region (const svalue *ap_sval)
{
if (const region *reg = ap_sval->maybe_get_region ())
return reg->dyn_cast_var_arg_region ();
- return NULL;
+ return nullptr;
}
/* Handler for "__builtin_va_arg". */