aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/sm-fd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/analyzer/sm-fd.cc')
-rw-r--r--gcc/analyzer/sm-fd.cc72
1 files changed, 46 insertions, 26 deletions
diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc
index cee8d2d..370d7a0 100644
--- a/gcc/analyzer/sm-fd.cc
+++ b/gcc/analyzer/sm-fd.cc
@@ -116,7 +116,11 @@ public:
const svalue *rhs) const final override;
bool can_purge_p (state_t s) const final override;
- 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;
bool is_unchecked_fd_p (state_t s) const;
bool is_valid_fd_p (state_t s) const;
@@ -210,7 +214,7 @@ public:
/* State for a file descriptor that we do not want to track anymore . */
state_t m_stop;
- /* Stashed constant values from the frontend. These could be NULL. */
+ /* Stashed constant values from the frontend. These could be NULL_TREE. */
tree m_O_ACCMODE;
tree m_O_RDONLY;
tree m_O_WRONLY;
@@ -257,7 +261,7 @@ private:
const svalue *fd_sval,
const supernode *node,
state_t old_state,
- bool *complained = NULL) const;
+ bool *complained = nullptr) const;
bool check_for_new_socket_fd (const call_details &cd,
bool successful,
sm_context &sm_ctxt,
@@ -397,11 +401,11 @@ public:
|| change.m_new_state == m_sm.m_new_datagram_socket
|| change.m_new_state == m_sm.m_new_stream_socket
|| change.m_new_state == m_sm.m_new_unknown_socket))
- 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_closed)
- 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 ();
}
@@ -422,7 +426,7 @@ public:
fd_param_diagnostic (const fd_state_machine &sm, tree arg, tree callee_fndecl)
: fd_diagnostic (sm, arg), m_callee_fndecl (callee_fndecl),
- m_attr_name (NULL), m_arg_idx (-1)
+ m_attr_name (nullptr), m_arg_idx (-1)
{
}
@@ -477,7 +481,14 @@ protected:
class fd_leak : public fd_diagnostic
{
public:
- fd_leak (const fd_state_machine &sm, tree arg) : fd_diagnostic (sm, arg) {}
+ fd_leak (const fd_state_machine &sm, tree arg,
+ const program_state *final_state)
+ : fd_diagnostic (sm, arg),
+ m_final_state ()
+ {
+ if (final_state)
+ m_final_state = std::make_unique<program_state> (*final_state);
+ }
const char *
get_kind () const final override
@@ -543,8 +554,15 @@ public:
return true;
}
+ const program_state *
+ get_final_state () const final override
+ {
+ return m_final_state.get ();
+ }
+
private:
diagnostic_event_id_t m_open_event;
+ std::unique_ptr<program_state> m_final_state;
};
class fd_access_mode_mismatch : public fd_param_diagnostic
@@ -1296,7 +1314,7 @@ fd_state_machine::valid_to_unchecked_state (state_t state) const
return m_unchecked_read_only;
else
gcc_unreachable ();
- return NULL;
+ return nullptr;
}
void
@@ -1305,7 +1323,7 @@ fd_state_machine::mark_as_valid_fd (region_model *model,
const svalue *fd_sval,
const extrinsic_state &ext_state) const
{
- smap->set_state (model, fd_sval, m_valid_read_write, NULL, ext_state);
+ smap->set_state (model, fd_sval, m_valid_read_write, nullptr, ext_state);
}
bool
@@ -1528,7 +1546,7 @@ fd_state_machine::on_open (sm_context &sm_ctxt, const supernode *node,
else
{
sm_ctxt.warn (node, stmt, NULL_TREE,
- std::make_unique<fd_leak> (*this, NULL_TREE));
+ std::make_unique<fd_leak> (*this, NULL_TREE, nullptr));
}
}
@@ -1541,7 +1559,7 @@ fd_state_machine::on_creat (sm_context &sm_ctxt, const supernode *node,
sm_ctxt.on_transition (node, stmt, lhs, m_start, m_unchecked_write_only);
else
sm_ctxt.warn (node, stmt, NULL_TREE,
- std::make_unique<fd_leak> (*this, NULL_TREE));
+ std::make_unique<fd_leak> (*this, NULL_TREE, nullptr));
}
void
@@ -1792,7 +1810,7 @@ fd_state_machine::on_socket (const call_details &cd,
}
else
sm_ctxt.warn (node, &call, NULL_TREE,
- std::make_unique<fd_leak> (*this, NULL_TREE));
+ std::make_unique<fd_leak> (*this, NULL_TREE, nullptr));
}
else
{
@@ -1967,7 +1985,7 @@ fd_state_machine::on_bind (const call_details &cd,
if (successful)
{
- state_t next_state = NULL;
+ state_t next_state = nullptr;
if (old_state == m_new_stream_socket)
next_state = m_bound_stream_socket;
else if (old_state == m_new_datagram_socket)
@@ -2185,7 +2203,7 @@ fd_state_machine::on_accept (const call_details &cd,
}
else
sm_ctxt.warn (node, &call, NULL_TREE,
- std::make_unique<fd_leak> (*this, NULL_TREE));
+ std::make_unique<fd_leak> (*this, NULL_TREE, nullptr));
}
else
{
@@ -2223,7 +2241,7 @@ fd_state_machine::on_connect (const call_details &cd,
if (successful)
{
model->update_for_zero_return (cd, true);
- state_t next_state = NULL;
+ state_t next_state = nullptr;
if (old_state == m_new_stream_socket)
next_state = m_connected_stream_socket;
else if (old_state == m_new_datagram_socket)
@@ -2321,9 +2339,11 @@ fd_state_machine::can_purge_p (state_t s) const
}
std::unique_ptr<pending_diagnostic>
-fd_state_machine::on_leak (tree var) const
+fd_state_machine::on_leak (tree var,
+ const program_state *,
+ const program_state *new_state) const
{
- return std::make_unique<fd_leak> (*this, var);
+ return std::make_unique<fd_leak> (*this, var, new_state);
}
} // namespace
@@ -2361,7 +2381,7 @@ region_model::mark_as_valid_fd (const svalue *sval, region_model_context *ctxt)
{
sm_state_map *smap;
const fd_state_machine *fd_sm;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, NULL))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, nullptr))
return;
const extrinsic_state *ext_state = ctxt->get_ext_state ();
if (!ext_state)
@@ -2390,7 +2410,7 @@ public:
sm_state_map *smap;
const fd_state_machine *fd_sm;
std::unique_ptr<sm_context> sm_ctxt;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt))
{
cd.set_any_lhs_with_defaults ();
return true;
@@ -2445,7 +2465,7 @@ public:
sm_state_map *smap;
const fd_state_machine *fd_sm;
std::unique_ptr<sm_context> sm_ctxt;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt))
{
cd.set_any_lhs_with_defaults ();
return true;
@@ -2498,7 +2518,7 @@ class kf_listen : public known_function
sm_state_map *smap;
const fd_state_machine *fd_sm;
std::unique_ptr<sm_context> sm_ctxt;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt))
{
cd.set_any_lhs_with_defaults ();
return true;
@@ -2552,7 +2572,7 @@ class kf_accept : public known_function
sm_state_map *smap;
const fd_state_machine *fd_sm;
std::unique_ptr<sm_context> sm_ctxt;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt))
{
cd.set_any_lhs_with_defaults ();
return true;
@@ -2609,7 +2629,7 @@ public:
sm_state_map *smap;
const fd_state_machine *fd_sm;
std::unique_ptr<sm_context> sm_ctxt;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt))
{
cd.set_any_lhs_with_defaults ();
return true;
@@ -2687,7 +2707,7 @@ class kf_isatty : public known_function
sm_state_map *smap;
const fd_state_machine *fd_sm;
std::unique_ptr<sm_context> sm_ctxt;
- if (!get_fd_state (ctxt, &smap, &fd_sm, NULL, &sm_ctxt))
+ if (!get_fd_state (ctxt, &smap, &fd_sm, nullptr, &sm_ctxt))
return true;
const extrinsic_state *ext_state = ctxt->get_ext_state ();
if (!ext_state)