From 4e4f9d578e037cd86453e517dde2856326d657d2 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 28 Feb 2019 17:26:28 -0500 Subject: [PATCH 019/169] FIXME: zero-assignment --- gcc/analyzer/engine.cc | 1 + gcc/analyzer/hardcoded-state-machine.cc | 29 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/malloc-1.c | 21 +++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 17d45c3..882e305 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -800,6 +800,7 @@ engine::on_stmt (const supernode *node, const gimple *stmt, case NOP_EXPR: case SSA_NAME: + case INTEGER_CST: { /* Direct assignment of the form LHS = RHS; */ on_assignment (node, assign, sm_inst, old_sm_inst, lhs, rhs1, ps); diff --git a/gcc/analyzer/hardcoded-state-machine.cc b/gcc/analyzer/hardcoded-state-machine.cc index 7c11e05..a6f4039 100644 --- a/gcc/analyzer/hardcoded-state-machine.cc +++ b/gcc/analyzer/hardcoded-state-machine.cc @@ -40,6 +40,25 @@ static const bool DEBUG = false; //////////////////////////////////////////////////////////////////////////// +/* If STMT is an assignment to zero, return the LHS. */ + +static tree +is_zero_assignment (const gimple *stmt) +{ + const gassign *assign_stmt = dyn_cast (stmt); + if (!assign_stmt) + return NULL_TREE; + + enum tree_code op = gimple_assign_rhs_code (assign_stmt); + if (op != INTEGER_CST) + return NULL_TREE; + + if (!zerop (gimple_assign_rhs1 (assign_stmt))) + return NULL_TREE; + + return gimple_assign_lhs (assign_stmt); +} + /* FIXME. */ static bool is_comparison_against_zero (const gcond *cond_stmt, @@ -132,6 +151,16 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, } } + /* FIXME: It's not clear if we need this, due to the SSA representation: + each assignment creates a new SSA_NAME. */ + if (tree lhs = is_zero_assignment (stmt)) + { + sm_ctxt->on_transition (node, stmt, lhs, m_start, m_null); + sm_ctxt->on_transition (node, stmt, lhs, m_unchecked, m_null); + sm_ctxt->on_transition (node, stmt, lhs, m_nonnull, m_null); + sm_ctxt->on_transition (node, stmt, lhs, m_free, m_null); + } + // TODO: dereferences for (unsigned i = 0; i < gimple_num_ops (stmt); i++) { diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c index ca5da1d..a5ef922 100644 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c @@ -189,3 +189,24 @@ void test_16 (void) /* TODO(xfail): implement uninitialized detection. */ free (p); } + +void test_17 (void) +{ + void *ptr = malloc (1024); /* { dg-error "leak of 'ptr'" "" { xfail *-*-* } } */ + /* TODO(xfail): implement leak detection. */ +} + +void test_18 (void) +{ + void *ptr = malloc (64); + ptr = NULL; /* { dg-error "leak of 'ptr'" "" { xfail *-*-* } } */ + /* TODO(xfail): implement leak detection. */ +} + +void test_19 (void) +{ + void *ptr = malloc (64); + free (ptr); + ptr = NULL; + free (ptr); +} -- 1.8.5.3