From 87455bc0cab65f11b52ef90118bdf2b0df551469 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 11 Jun 2020 15:14:36 -0400 Subject: [PATCH 227/315] FIXME: fix merger of widening_svalue2s --- gcc/analyzer/region-model2.cc | 48 +++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index 3882334d7de..5e3a1ac637a 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -277,14 +277,26 @@ svalue2::can_merge_p (const svalue2 *other, if (other == widen_sval->get_iter_svalue2 ()) return this; } - /* Merge: (Widen BINOP X), Y -> Widen - FIXME: what conditions? */ + if (const binop_svalue2 *binop_sval = dyn_cast_binop_svalue2 ()) if (const widening_svalue2 *widen_arg0 = binop_sval->get_arg0 ()->dyn_cast_widening_svalue2 ()) { - // FIXME! - return widen_arg0; + if (other == binop_sval->get_arg1 ()) + { + /* Merger of: (Widen(..., OTHER) BINOP X) + and : OTHER + to : (Widen(..., OTHER) BINOP X) + e.g. merge of Widen(0, 1) + 1 with 1 to the Widen(0, 1) + 1. */ + return this; + } + + /* Merger of : (Widen() BINOP X) + and : Widen() + to : Widen() + e.g. merge of Widen(0, 1) + 1 and Widen(0, 1) to Widen(0, 1). */ + if (other == widen_arg0) + return widen_arg0; } #endif @@ -5732,6 +5744,7 @@ region_model2::get_rvalue_1 (path_var pv, } /* Binary ops. */ + case PLUS_EXPR: case MULT_EXPR: { tree expr = pv.m_tree; @@ -9922,7 +9935,7 @@ test_constraint_merging () {i_11: WIDENED (at phi, 0, 1); WIDENED <= 255} i_23 = i_11 + 1; {i_23: (WIDENED (at phi, 0, 1) + 1); WIDENED <= 255} - i_11 = PHI() + i_11 = PHI(); merge with state at phi above {i_11: WIDENED (at phi, 0, 1); WIDENED <= 256} [changing meaning of "WIDENED" here] if (i_11 <= 255) @@ -9979,6 +9992,31 @@ test_iteration_1 () /* ...and we should have equality: the analysis should have converged. */ ASSERT_EQ (model3, model2); + /* "i_23 = i_11 + 1;" */ + region_model2 model4 (model3); + ASSERT_EQ (model4, model2); + model4.set_value (i, build2 (PLUS_EXPR, integer_type_node, i, int_1), &ctxt); + const svalue2 *plus_one = model4.get_rvalue (i, &ctxt); + /* TODO: what should this be? + Currently it's the widening(0, +ve) plus one. + Should it be a new widening(1, +ve), and apply a reworked version + of the constraints on the other widening value? */ + ASSERT_EQ (plus_one->get_kind (), svalue2::SK_BINOP); + + /* Try merging with the "i: 1" state. */ + region_model2 model5 (&mgr); + ASSERT_TRUE (model4.can_merge_with_p (model1, point, &model5)); + ASSERT_EQ (model5.get_rvalue (i, &ctxt), plus_one); + ASSERT_EQ (model5, model4); + + /* "i_11 = PHI();" merge with state at phi above. + For i, we should have a merger of WIDENING with WIDENING + 1, + and this should be WIDENING again. */ + region_model2 model6 (&mgr); + ASSERT_TRUE (model5.can_merge_with_p (model2, point, &model6)); + const svalue2 *merged_widening = model6.get_rvalue (i, &ctxt); + ASSERT_EQ (merged_widening->get_kind (), svalue2::SK_WIDENING); + // TODO #endif } -- 2.26.2