public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/arsenic/heads/polymorphic_call)] analyzer: detect and analyzer vfunc calls
@ 2021-08-01 9:21 Ankur saini
0 siblings, 0 replies; only message in thread
From: Ankur saini @ 2021-08-01 9:21 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:450989a9458e3d0087b01a2bb04b7667fb60afb5
commit 450989a9458e3d0087b01a2bb04b7667fb60afb5
Author: Ankur Saini <arsenic@sourceware.org>
Date: Thu Jul 29 17:20:10 2021 +0530
analyzer: detect and analyzer vfunc calls
Diff:
---
gcc/analyzer/engine.cc | 61 ++++++++++++++++++++++++++++++++++++++-----
gcc/analyzer/program-state.cc | 5 ++--
gcc/analyzer/program-state.h | 3 ++-
gcc/analyzer/region-model.cc | 11 +++++---
gcc/analyzer/region-model.h | 3 ++-
5 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 29209030b5b..f4cf0864008 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see
#include <zlib.h>
#include "plugin.h"
#include "target.h"
+#include "ipa-utils.h"
/* For an overview, see gcc/doc/analyzer.texi. */
@@ -1242,6 +1243,17 @@ exploded_node::on_stmt (exploded_graph &eg,
unknown_side_effects = false;
}
+ /* If the statmement is a polymorphic call then assume
+ there are no side effects. */
+ gimple *call_stmt = const_cast<gimple *>(stmt);
+ if (gcall *call = dyn_cast<gcall *> (call_stmt))
+ {
+ function *fun = this->get_function();
+ cgraph_edge *e = cgraph_node::get (fun->decl)->get_edge (call);
+ if ((e && e->indirect_info) && (e->indirect_info->polymorphic))
+ unknown_side_effects = false;
+ }
+
on_stmt_post (stmt, state, unknown_side_effects, &ctxt);
return on_stmt_flags ();
@@ -3035,12 +3047,11 @@ void
exploded_graph::create_dynamic_call (const gcall *call,
tree fn_decl,
exploded_node *node,
- program_state &next_state,
+ program_state next_state,
program_point &next_point,
uncertainty_t *uncertainty)
{
const program_point *this_point = &node->get_point ();
- // assert for fn_decl ?
function *fun = DECL_STRUCT_FUNCTION (fn_decl);
if (fun)
{
@@ -3055,7 +3066,7 @@ exploded_graph::create_dynamic_call (const gcall *call,
new_point.push_to_call_stack (sn_exit,
next_point.get_supernode());
- next_state.push_call (*this, node, call, uncertainty);
+ next_state.push_call (*this, node, call, uncertainty, fn_decl);
// TODO: add some logging here regarding dynamic call
@@ -3327,9 +3338,47 @@ exploded_graph::process_node (exploded_node *node)
region_model *model = state.m_region_model;
/* Call is possibly happening via a function pointer. */
- if (tree fn_decl = model->get_fndecl_for_call(call,&ctxt))
- create_dynamic_call (call, fn_decl, node, next_state,
- next_point, &uncertainty);
+ if (tree fn_decl = model->get_fndecl_for_call (call,&ctxt))
+ create_dynamic_call (call,
+ fn_decl,
+ node,
+ next_state,
+ next_point,
+ &uncertainty);
+ else
+ {
+ /* Call is possibly a polymorphic call.
+
+ In such case, use devirtisation tools to find
+ possible callees of this function call and let the
+ analyzer specluate them all. */
+ function *fun = node->get_function ();
+ gcall *stmt = const_cast<gcall *>(call);
+ cgraph_edge *e
+ = cgraph_node::get (fun->decl)->get_edge (stmt);
+ if (e->indirect_info->polymorphic)
+ {
+ void *cache_token;
+ bool final;
+ vec <cgraph_node *> targets
+ = possible_polymorphic_call_targets (e,
+ &final,
+ &cache_token,
+ true);
+ for (cgraph_node *x : targets)
+ {
+ if (logger)
+ logger->log ("found call to : %s\n",
+ x->dump_name());
+ create_dynamic_call (stmt,
+ x->decl,
+ node,
+ next_state,
+ next_point,
+ &uncertainty);
+ }
+ }
+ }
}
if (!node->on_edge (*this, succ, &next_point, &next_state,
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index eb05994f0ef..b1c1d67bb8b 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -1042,7 +1042,8 @@ void
program_state::push_call (exploded_graph &eg,
exploded_node *enode,
const gcall *call_stmt,
- uncertainty_t *uncertainty)
+ uncertainty_t *uncertainty,
+ tree fn_decl)
{
/* Update state. */
const program_point &point = enode->get_point ();
@@ -1053,7 +1054,7 @@ program_state::push_call (exploded_graph &eg,
this,
uncertainty,
last_stmt);
- m_region_model->update_for_gcall (call_stmt, &ctxt);
+ m_region_model->update_for_gcall(call_stmt, &ctxt, fn_decl);
}
/* Update this program_state to reflect a return from function
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index 658dbb69075..f4bd4cbcf49 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -221,7 +221,8 @@ public:
void push_call (exploded_graph &eg,
exploded_node *enode,
const gcall *call_stmt,
- uncertainty_t *uncertainty);
+ uncertainty_t *uncertainty,
+ tree fn_decl = NULL);
void returning_call (exploded_graph &eg,
exploded_node *enode,
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 1e86d1f3bf8..935a8c6431a 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3140,7 +3140,8 @@ region_model::maybe_update_for_edge (const superedge &edge,
void
region_model::update_for_gcall (const gcall *call_stmt,
- region_model_context *ctxt)
+ region_model_context *ctxt,
+ tree fn_decl)
{
/* Build a vec of argument svalues, using the current top
frame for resolving tree expressions. */
@@ -3151,9 +3152,11 @@ region_model::update_for_gcall (const gcall *call_stmt,
tree arg = gimple_call_arg (call_stmt, i);
arg_svals.quick_push (get_rvalue (arg, ctxt));
}
-
- /* Get the function * from the call. */
- tree fn_decl = get_fndecl_for_call (call_stmt,ctxt);
+
+ /* Get the fn_decl from the call if not provided as argument. */
+ if (!fn_decl)
+ fn_decl = get_fndecl_for_call (call_stmt,ctxt);
+
function *fun = DECL_STRUCT_FUNCTION (fn_decl);
push_frame (fun, &arg_svals, ctxt);
}
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index a15bc9e2f6d..f06788771dc 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -590,7 +590,8 @@ class region_model
rejected_constraint **out);
void update_for_gcall (const gcall *call_stmt,
- region_model_context *ctxt);
+ region_model_context *ctxt,
+ tree fn_decl = NULL);
void update_for_return_gcall (const gcall *call_stmt,
region_model_context *ctxt);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-08-01 9:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-01 9:21 [gcc(refs/users/arsenic/heads/polymorphic_call)] analyzer: detect and analyzer vfunc calls Ankur saini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).