public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3052] analyzer: Fix PR analyzer/101980
@ 2021-08-21 5:04 Ankur saini
0 siblings, 0 replies; only message in thread
From: Ankur saini @ 2021-08-21 5:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e92d0ff6b5e6d4b95c04fc3e326d40efeb136086
commit r12-3052-ge92d0ff6b5e6d4b95c04fc3e326d40efeb136086
Author: Ankur Saini <arsenic@sourceware.org>
Date: Thu Aug 19 19:54:56 2021 +0530
analyzer: Fix PR analyzer/101980
2021-08-19 Ankur Saini <arsenic@sourceware.org>
gcc/analyzer/ChangeLog:
PR analyzer/101980
* diagnostic-manager.cc
(diagnostic_manager::prune_for_sm_diagnostic)<case EK_CALL_EDGE>: Use
caller_model only when the supergraph_edge doesn't exixt.
(diagnostic_manager::prune_for_sm_diagnostic)<case EK_RETURN_EDGE>:
Likewise.
* engine.cc (exploded_graph::create_dynamic_call): Rename to...
(exploded_graph::maybe_create_dynamic_call): ...this, return call
creation status.
(exploded_graph::process_node): Handle calls which were not dynamically
discovered.
* exploded-graph.h (exploded_graph::create_dynamic_call): Rename to...
(exploded_graph::maybe_create_dynamic_call): ...this.
* region-model.cc (region_model::update_for_gcall): New param, use it
to push call to frame.
(region_model::update_for_call_superedge): Pass callee function to
update_for_gcall.
* region-model.h (region_model::update_for_gcall): New param.
gcc/testsuite/ChangeLog:
PR analyzer/101980
* gcc.dg/analyzer/function-ptr-2.c : Add issue for double 'free'.
* gcc.dg/analyzer/malloc-callbacks.c : Fix xfail testcase.
Diff:
---
gcc/analyzer/diagnostic-manager.cc | 40 +++++++++++++++++--
gcc/analyzer/engine.cc | 49 +++++++++++++-----------
gcc/analyzer/exploded-graph.h | 14 +++----
gcc/analyzer/region-model.cc | 17 +++++---
gcc/analyzer/region-model.h | 3 +-
gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c | 5 +--
gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c | 2 +-
7 files changed, 85 insertions(+), 45 deletions(-)
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index 06e751033ac..89b5d1e3c3c 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -2099,7 +2099,22 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
= event->m_eedge.m_src->get_state ().m_region_model;
tree callee_var = callee_model->get_representative_tree (sval);
callsite_expr expr;
- tree caller_var = caller_model->get_representative_tree (sval);
+
+ tree caller_var;
+ if(event->m_sedge)
+ {
+ const callgraph_superedge& cg_superedge
+ = event->get_callgraph_superedge ();
+ if (cg_superedge.m_cedge)
+ caller_var
+ = cg_superedge.map_expr_from_callee_to_caller (callee_var,
+ &expr);
+ else
+ callee_var = callee_model->get_representative_tree (sval);
+ }
+ else
+ caller_var = caller_model->get_representative_tree (sval);
+
if (caller_var)
{
if (get_logger ())
@@ -2121,11 +2136,28 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
if (sval)
{
return_event *event = (return_event *)base_event;
+ const region_model *caller_model
+ = event->m_eedge.m_dest->get_state ().m_region_model;
+ tree caller_var = caller_model->get_representative_tree (sval);
+ const region_model *callee_model
+ = event->m_eedge.m_src->get_state ().m_region_model;
callsite_expr expr;
- const region_model *callee_model
- = event->m_eedge.m_src->get_state ().m_region_model;
- tree callee_var = callee_model->get_representative_tree (sval);
+ tree callee_var;
+ if (event->m_sedge)
+ {
+ const callgraph_superedge& cg_superedge
+ = event->get_callgraph_superedge ();
+ if (cg_superedge.m_cedge)
+ callee_var
+ = cg_superedge.map_expr_from_caller_to_callee (caller_var,
+ &expr);
+ else
+ callee_var = callee_model->get_representative_tree (sval);
+ }
+ else
+ callee_var = callee_model->get_representative_tree (sval);
+
if (callee_var)
{
if (get_logger ())
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 461de9cf77c..e66ca4e42fd 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -3033,14 +3033,14 @@ state_change_requires_new_enode_p (const program_state &old_state,
Some example such calls are dynamically dispatched calls to virtual
functions or calls that happen via function pointer. */
-void
-exploded_graph::create_dynamic_call (const gcall *call,
- tree fn_decl,
- exploded_node *node,
- program_state next_state,
- program_point &next_point,
- uncertainty_t *uncertainty,
- logger *logger)
+bool
+exploded_graph::maybe_create_dynamic_call (const gcall *call,
+ tree fn_decl,
+ exploded_node *node,
+ program_state next_state,
+ program_point &next_point,
+ uncertainty_t *uncertainty,
+ logger *logger)
{
LOG_FUNC (logger);
@@ -3049,8 +3049,8 @@ exploded_graph::create_dynamic_call (const gcall *call,
if (fun)
{
const supergraph &sg = this->get_supergraph ();
- supernode * sn_entry = sg.get_node_for_function_entry (fun);
- supernode * sn_exit = sg.get_node_for_function_exit (fun);
+ supernode *sn_entry = sg.get_node_for_function_entry (fun);
+ supernode *sn_exit = sg.get_node_for_function_exit (fun);
program_point new_point
= program_point::before_supernode (sn_entry,
@@ -3075,8 +3075,10 @@ exploded_graph::create_dynamic_call (const gcall *call,
if (enode)
add_edge (node,enode, NULL,
new dynamic_call_info_t (call));
+ return true;
}
- }
+ }
+ return false;
}
/* The core of exploded_graph::process_worklist (the main analysis loop),
@@ -3338,22 +3340,23 @@ exploded_graph::process_node (exploded_node *node)
point.get_stmt());
region_model *model = state.m_region_model;
+ bool call_discovered = false;
if (tree fn_decl = model->get_fndecl_for_call(call,&ctxt))
- create_dynamic_call (call,
- fn_decl,
- node,
- next_state,
- next_point,
- &uncertainty,
- logger);
- else
+ call_discovered = maybe_create_dynamic_call (call,
+ fn_decl,
+ node,
+ next_state,
+ next_point,
+ &uncertainty,
+ logger);
+ if (!call_discovered)
{
- /* An unknown function was called at this point, in such
- case, don't terminate the analysis of the current
- function.
+ /* An unknown function or a special function was called
+ at this point, in such case, don't terminate the
+ analysis of the current function.
- The analyzer handles calls to unknown functions while
+ The analyzer handles calls to such functions while
analysing the stmt itself, so the the function call
must have been handled by the anlyzer till now. */
exploded_node *next
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index 192a4b3c8f8..6890e84f985 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -816,13 +816,13 @@ public:
bool maybe_process_run_of_before_supernode_enodes (exploded_node *node);
void process_node (exploded_node *node);
- void create_dynamic_call (const gcall *call,
- tree fn_decl,
- exploded_node *node,
- program_state next_state,
- program_point &next_point,
- uncertainty_t *uncertainty,
- logger *logger);
+ bool maybe_create_dynamic_call (const gcall *call,
+ tree fn_decl,
+ exploded_node *node,
+ program_state next_state,
+ program_point &next_point,
+ uncertainty_t *uncertainty,
+ logger *logger);
exploded_node *get_or_create_node (const program_point &point,
const program_state &state,
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 822e893e899..9870007e57e 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3178,7 +3178,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,
+ function *callee)
{
/* Build a vec of argument svalues, using the current top
frame for resolving tree expressions. */
@@ -3190,10 +3191,14 @@ region_model::update_for_gcall (const gcall *call_stmt,
arg_svals.quick_push (get_rvalue (arg, ctxt));
}
- /* Get the function * from the call. */
- tree fn_decl = get_fndecl_for_call (call_stmt,ctxt);
- function *fun = DECL_STRUCT_FUNCTION (fn_decl);
- push_frame (fun, &arg_svals, ctxt);
+ if(!callee)
+ {
+ /* Get the function * from the gcall. */
+ tree fn_decl = get_fndecl_for_call (call_stmt,ctxt);
+ callee = DECL_STRUCT_FUNCTION (fn_decl);
+ }
+
+ push_frame (callee, &arg_svals, ctxt);
}
/* Pop the top-most frame_region from the stack, and copy the return
@@ -3228,7 +3233,7 @@ region_model::update_for_call_superedge (const call_superedge &call_edge,
region_model_context *ctxt)
{
const gcall *call_stmt = call_edge.get_call_stmt ();
- update_for_gcall (call_stmt,ctxt);
+ update_for_gcall (call_stmt, ctxt, call_edge.get_callee_function ());
}
/* Extract calling information from the return superedge and update the model
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index e40264e0eb0..a734f9f7315 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -609,7 +609,8 @@ class region_model
rejected_constraint **out);
void update_for_gcall (const gcall *call_stmt,
- region_model_context *ctxt);
+ region_model_context *ctxt,
+ function *callee = NULL);
void update_for_return_gcall (const gcall *call_stmt,
region_model_context *ctxt);
diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c b/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c
index 411b1b39377..fd25e3be40b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/function-ptr-2.c
@@ -6,9 +6,10 @@ typedef void (*fn_ptr_t) (void *);
void
calls_free (void *victim)
{
- free (victim);
+ free (victim); /* { dg-warning "double-'free' of 'victim'" } */
}
+
void
no_op (void *ptr)
{
@@ -25,7 +26,6 @@ void test_1 (void *ptr)
fn_ptr (ptr);
fn_ptr (ptr);
}
-// TODO: issue a double-'free' warning at 2nd call to fn_ptr.
/* As above, but with an extra indirection to try to thwart
the optimizer. */
@@ -41,4 +41,3 @@ void test_2 (void *ptr, fn_ptr_t *fn_ptr)
(*fn_ptr) (ptr);
(*fn_ptr) (ptr);
}
-// TODO: issue a double-'free' warning at 2nd call to fn_ptr.
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c
index 901ca5c46fd..53c75fddf84 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-callbacks.c
@@ -69,7 +69,7 @@ int *test_5 (void)
static void __attribute__((noinline))
called_by_test_6a (void *ptr)
{
- free (ptr); /* { dg-warning "double-'free'" "" { xfail *-*-* } } */
+ free (ptr); /* { dg-warning "double-'free'"} */
}
static deallocator_t __attribute__((noinline))
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-08-21 5:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-21 5:04 [gcc r12-3052] analyzer: Fix PR analyzer/101980 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).