From 891c34436905682f0d33105173fc65b8b9f75251 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 13 May 2020 16:21:34 -0400 Subject: [PATCH 130/179] FIXME: add cast in region_model2::get_store_value; fold away unnecessary casts --- gcc/analyzer/region-model2.cc | 58 +++++++++++++++++++++++++++++++---- gcc/analyzer/region-model2.h | 1 + 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index 9357822bd89..3e8b73c3896 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -2689,6 +2689,10 @@ const svalue2 * region_model2_manager::maybe_fold_unaryop (tree type, enum tree_code op, const svalue2 *arg) { + /* Handle redundant casts. */ + if (op == NOP_EXPR && useless_type_conversion_p (arg->get_type (), type)) + return arg; + /* Constants. */ if (tree cst = arg->maybe_get_constant ()) if (tree result = fold_unary (op, type, cst)) @@ -2710,6 +2714,12 @@ region_model2_manager::get_or_create_unaryop (tree type, enum tree_code op, return unaryop_sval; } +const svalue2 * +region_model2_manager::get_or_create_cast (tree type, const svalue2 *arg) +{ + return get_or_create_unaryop (type, NOP_EXPR, arg); +} + const svalue2 * region_model2_manager::maybe_fold_binop (tree type, enum tree_code op, const svalue2 *arg0, const svalue2 *arg1) @@ -5068,7 +5078,7 @@ region_model2::get_store_value (const region2 *reg) const svalue2 *sval = m_store.get_any_binding (m_mgr->get_store2_manager (), reg); if (sval) - return sval; + return m_mgr->get_or_create_cast (reg->get_type (), sval); /* Special-case: read at a constant index within a STRING_CST. */ if (const offset_region2 *offset_reg = reg->dyn_cast_offset_region2 ()) @@ -7831,10 +7841,47 @@ test_region2_equality () } #endif +/* Verify that unary ops are folded as expected. */ + +static void +test_initial_svalue2_folding () +{ + region_model2_manager mgr; + tree x = build_global_decl ("x", integer_type_node); + + test_region_model2_context ctxt; + region_model2 model (&mgr); + const svalue2 *x_init = model.get_rvalue (x, &ctxt); + const region2 *x_reg = model.get_lvalue (x, &ctxt); + ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg)); + +} + +/* Verify unary ops are folded as expected. */ + +static void +test_unaryop_svalue2_folding () +{ + region_model2_manager mgr; + tree x = build_global_decl ("x", integer_type_node); + + test_region_model2_context ctxt; + region_model2 model (&mgr); + const svalue2 *x_init = model.get_rvalue (x, &ctxt); + const region2 *x_reg = model.get_lvalue (x, &ctxt); + ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg)); + + /* "(int)x" -> "x". */ + ASSERT_EQ (x_init, mgr.get_or_create_cast (integer_type_node, x_init)); + + /* "(void *nt)x" -> something other than "x". */ + ASSERT_NE (x_init, mgr.get_or_create_cast (ptr_type_node, x_init)); +} + /* Verify that binops on constant svalues are folded. */ static void -test_svalue2_folding () +test_binop_svalue2_folding () { #define NUM_CSTS 10 tree cst_int[NUM_CSTS]; @@ -7884,13 +7931,10 @@ test_svalue2_folding () } tree x = build_global_decl ("x", integer_type_node); - tree y = build_global_decl ("y", integer_type_node); test_region_model2_context ctxt; region_model2 model (&mgr); const svalue2 *x_init = model.get_rvalue (x, &ctxt); - const region2 *x_reg = model.get_lvalue (x, &ctxt); - ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg)); /* PLUS_EXPR folding. */ const svalue2 *x_init_plus_zero @@ -9292,7 +9336,9 @@ analyzer_region_model2_cc_tests () test_svalue2_equality (); test_region2_equality (); #endif - test_svalue2_folding (); + test_initial_svalue2_folding (); + test_unaryop_svalue2_folding (); + test_binop_svalue2_folding (); #if 0 test_purging_by_criteria (); test_purge_unused_svalue2s (); diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h index e9eadaa3830..aceb7e9240a 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -1574,6 +1574,7 @@ public: const svalue2 *get_ptr_svalue2 (tree ptr_type, const region2 *pointee); const svalue2 *get_or_create_unaryop (tree type, enum tree_code op, const svalue2 *arg); + const svalue2 *get_or_create_cast (tree type, const svalue2 *arg); const svalue2 *get_or_create_binop (tree type, enum tree_code op, const svalue2 *arg0, const svalue2 *arg1); -- 2.21.0