From faa6796767db3260ede0f9b180999377ccd01cda Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 15 May 2020 12:19:06 -0400 Subject: [PATCH 138/179] FIXME: subvalues of 'unknown' are unknown --- gcc/analyzer/region-model2.cc | 68 +++++++++++++++++++++++++++++++---- gcc/analyzer/region-model2.h | 3 ++ 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index 4723d8577f4..17c8f9a5739 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -525,9 +525,17 @@ void unknown_svalue2::dump_to_pp (pretty_printer *pp, bool simple) const { if (simple) - pp_printf (pp, "UNKNOWN"); + { + pp_string (pp, "UNKNOWN("); + dump_tree (pp, get_type ()); + pp_character (pp, ')'); + } else - pp_printf (pp, "unknown_svalue2()"); + { + pp_string (pp, "unknown_svalue2("); + dump_tree (pp, get_type ()); + pp_character (pp, ')'); + } } /* class poisoned_svalue2 : public svalue2. */ @@ -2824,14 +2832,19 @@ maybe_get_char_from_string_cst (tree string_cst, tree byte_offset_cst, return NULL; } -/* FIXME. */ +/* Subroutine of region_model2_manager::get_or_create_sub_svalue2. + Return a folded svalue2, or NULL. */ const svalue2 * -region_model2_manager::get_or_create_sub_svalue2 (tree type, - const svalue2 *parent_svalue2, - const region2 *subregion) +region_model2_manager::maybe_fold_sub_svalue2 (tree type, + const svalue2 *parent_svalue2, + const region2 *subregion) { - /* Specialcase: if we have a subregion of a zero-fill, it's zero. */ + /* Subvalues of "unknown" are unknown. */ + if (parent_svalue2->get_kind () == svalue2::SK_UNKNOWN) + return get_or_create_unknown_svalue2 (type); + + /* If we have a subregion of a zero-fill, it's zero. */ if (const unaryop_svalue2 *unary = parent_svalue2->dyn_cast_unaryop_svalue2 ()) { @@ -2858,6 +2871,20 @@ region_model2_manager::get_or_create_sub_svalue2 (tree type, return get_or_create_cast (type, char_sval); } + return NULL; +} + +/* FIXME. */ + +const svalue2 * +region_model2_manager::get_or_create_sub_svalue2 (tree type, + const svalue2 *parent_svalue2, + const region2 *subregion) +{ + if (const svalue2 *folded + = maybe_fold_sub_svalue2 (type, parent_svalue2, subregion)) + return folded; + sub_svalue2::key_t key (type, parent_svalue2, subregion); if (sub_svalue2 **slot = m_sub_values_map.get (key)) return *slot; @@ -7958,6 +7985,32 @@ test_binop_svalue2_folding () /* FIXME: do we want to canonicalize binops to put constants on the RHS ? */ } + +/* Verify that sub_svalue2s are folded as expected. */ + +static void +test_sub_svalue2_folding () +{ + coord_test2 ct; + tree c = build_global_decl ("c", ct.m_coord_type); + tree c_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field), + c, ct.m_x_field, NULL_TREE); + + region_model2_manager mgr; + region_model2 model (&mgr); + test_region_model2_context ctxt; + const region2 *c_x_reg = model.get_lvalue (c_x, &ctxt); + + /* Verify that sub_svalue2 of "unknown" simply + yields an unknown. */ + + const svalue2 *unknown = mgr.get_or_create_unknown_svalue2 (ct.m_coord_type); + const svalue2 *sub = mgr.get_or_create_sub_svalue2 (TREE_TYPE (ct.m_x_field), + unknown, c_x_reg); + ASSERT_EQ (sub->get_kind (), svalue2::SK_UNKNOWN); + ASSERT_EQ (sub->get_type (), TREE_TYPE (ct.m_x_field)); +} + #if 0 /* A subclass of purge_criteria for selftests: purge all const svalue2 *instances. */ @@ -9352,6 +9405,7 @@ analyzer_region_model2_cc_tests () test_initial_svalue2_folding (); test_unaryop_svalue2_folding (); test_binop_svalue2_folding (); + test_sub_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 c84999a72a2..0aee4001d7e 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -1616,6 +1616,9 @@ private: const svalue2 *arg); const svalue2 *maybe_fold_binop (tree type, enum tree_code op, const svalue2 *arg0, const svalue2 *arg1); + const svalue2 *maybe_fold_sub_svalue2 (tree type, + const svalue2 *parent_svalue, + const region2 *subregion); unsigned m_next_region_id; root_region2 m_root_region; -- 2.21.0