From 4482e03418271a0dba2286c3a192915ef1fcb8db Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 26 May 2020 17:54:02 -0400 Subject: [PATCH 183/315] FIXME: fold associative ops; add refcounting test --- gcc/analyzer/region-model2.cc | 43 +++++++++++++------ gcc/testsuite/gcc.dg/analyzer/refcounting-1.c | 31 +++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/refcounting-1.c diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index 70faab6366f..323b040b125 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -3008,6 +3008,23 @@ region_model2_manager::maybe_fold_binop (tree type, enum tree_code op, } break; } + + /* For associative ops, fold "(X op CST_A) op CST_B)" to + "X op (CST_A op CST_B)". */ + if (cst1 && associative_tree_code (op)) + if (const binop_svalue2 *binop = arg0->dyn_cast_binop_svalue2 ()) + if (binop->get_op () == op + && binop->get_arg1 ()->maybe_get_constant () + && type == binop->get_type () + && type == binop->get_arg0 ()->get_type () + && type == binop->get_arg1 ()->get_type ()) + return get_or_create_binop + (type, op, binop->get_arg0 (), + get_or_create_binop (type, op, + binop->get_arg1 (), arg1)); + + // TODO + return NULL; } @@ -8279,20 +8296,6 @@ test_binop_svalue2_folding () // etc // TODO: do we want to use the match-and-simplify DSL for this? - /* TODO: Verify that ((x + 1) + 1) == (x + 2). */ - const svalue2 *x_init_plus_one - = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR, - x_init, cst_sval[1]); - const svalue2 *x_init_plus_two - = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR, - x_init, cst_sval[2]); - const svalue2 *x_init_plus_one_plus_one - = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR, - x_init_plus_one, cst_sval[1]); -#if 0 - ASSERT_EQ (x_init_plus_one_plus_one, x_init_plus_two); -#endif - /* Verify that binops put any constants on the RHS. */ const svalue2 *four_times_x_init = mgr.get_or_create_binop (integer_type_node, MULT_EXPR, @@ -8305,6 +8308,18 @@ test_binop_svalue2_folding () ASSERT_EQ (binop->get_op (), MULT_EXPR); ASSERT_EQ (binop->get_arg0 (), x_init); ASSERT_EQ (binop->get_arg1 (), cst_sval[4]); + + /* Verify that ((x + 1) + 1) == (x + 2). */ + const svalue2 *x_init_plus_one + = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR, + x_init, cst_sval[1]); + const svalue2 *x_init_plus_two + = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR, + x_init, cst_sval[2]); + const svalue2 *x_init_plus_one_plus_one + = mgr.get_or_create_binop (integer_type_node, PLUS_EXPR, + x_init_plus_one, cst_sval[1]); + ASSERT_EQ (x_init_plus_one_plus_one, x_init_plus_two); } /* Verify that sub_svalue2s are folded as expected. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/refcounting-1.c b/gcc/testsuite/gcc.dg/analyzer/refcounting-1.c new file mode 100644 index 00000000000..4eb3a3e6ff2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/refcounting-1.c @@ -0,0 +1,31 @@ +#include "analyzer-decls.h" + +typedef struct obj { + int ob_refcnt; +} PyObject; + +extern void Py_Dealloc (PyObject *op); + +#define Py_INCREF(op) \ + do { \ + ((PyObject*)(op))->ob_refcnt++; \ + } while (0) + +#define Py_DECREF(op) \ + do { \ + if (--((PyObject*)(op))->ob_refcnt == 0) \ + { \ + /*Py_Dealloc((PyObject *)(op));*/ \ + } \ + } while (0) + +void test_1 (PyObject *obj) +{ + int orig_refcnt = obj->ob_refcnt; + Py_INCREF (obj); + Py_INCREF (obj); + Py_DECREF (obj); + Py_INCREF (obj); + __analyzer_eval (obj->ob_refcnt == orig_refcnt + 2); /* { dg-warning "TRUE" } */ +} +/* TODO: uncomment the Py_Dealloc, which leads to two paths. */ -- 2.26.2