class region_model_manager consolidates and manages svalue and region
instances. I'm about to add various new subclasses of symbolic::node,
each with their own manager class.
This patch adds a new symbolic::node_manager class to be a "hub" that
all the various node manager classes will be able to access.
For now, we merely moves region_model_manager from being a top-level
object to being one owned by node_manager; followup patches will add
more managers for more kinds of symbolic::node.
gcc/analyzer/ChangeLog:
* access-diagram.cc: Update for introduction of
symbolic::node_manager, creating node_manager and
accessing its region_model_manager rather than creating
the latter directly.
* common.h (class symbolic::node_manager): New forward decl.
(class call_string): Likewise.
* constraint-manager.cc: Update for introduction of
symbolic::node_manager, creating node_manager instances and
accessing their region_model_manager rather than creating
instances of the latter directly. Update for region_model ctor
taking a node_manager & rather than a region_model_manager *.
* diagnostic-manager.cc: Likewise.
* engine.cc: Likewise.
* program-point.cc: Likewise.
* program-state.cc: Likewise.
* program-state.h: Likewise.
* ranges.cc: Likewise.
* region-model-manager.cc
(region_model_manager::region_model_manager): Add "node_mgr" param
and use it to initialize m_node_mgr. Update for move of
m_next_node_id into node_manager.
(region_model_manager::log_stats): Drop logging of m_next_node_id.
* region-model-manager.h
(region_model_manager::region_model_manager): Add "node_mgr"
param.
(region_model_manager::get_num_nodes): Move to node_manager.
(region_model_manager::alloc_node_id): Delegate to m_node_mgr.
(region_model_manager::get_node_manager): New accessor.
(region_model_manager::m_node_mgr): New field.
(region_model_manager::m_next_node_id): Move to node_manager.
* region-model.cc (region_model::region_model): Update param from
region_model_manager * to symbolic::node_manager &.
(engine::engine): Update for introduction of node_manager.
(engine::log_stats): Likewise.
(selftest) Update selftests for introduction of
symbolic::node_manager, creating node_manager instances and
accessing their region_model_manager rather than creating
instances of the latter directly. Update for region_model ctor
taking a node_manager & rather than a region_model_manager *.
* region-model.h (region_model::region_model): Change param from
region_model_manager * to symbolic::node_manager &.
(region_model::get_node_manager): New accessor.
(region_model::m_node_mgr): New field.
(engine::engine): Change param from region_model_manager & to
symbolic::node_manager &.
(engine::get_node_manager): New.
(engine::get_model_manager): New.
(engine::get_known_function_manager): Update.
(engine::m_mgr): Replace field with...
(engine::m_node_mgr): ...this.
* region.cc: Update for region_model ctor taking a node_manager &
rather than a region_model_manager *.
* sm-signal.cc (update_model_for_signal_handler): Likewise.
* state-purge.cc (state_purge_per_decl::process_worklists):
Likewise.
* store.cc (get_svalue_for_ctor_val): Likewise.
(selftest::test_binding_key_overlap): Update for introduction of
symbolic::node_manager
* symbolic-nodes.cc: Include "analyzer/analyzer-logging.h",
"analyzer/region-model.h", and "analyzer/region-model-manager.h".
(symbolic::node_manager::node_manager): New.
(ymbolic::node_manager::~node_manager): New.
(symbolic::node_manager::log_stats): New.
* symbolic-nodes.h (class node_manager): New.
Signed-off-by: David Malcolm <[email protected]>
---
gcc/analyzer/access-diagram.cc | 3 +-
gcc/analyzer/common.h | 2 +
gcc/analyzer/constraint-manager.cc | 295 +++++++++++++++------------
gcc/analyzer/diagnostic-manager.cc | 2 +-
gcc/analyzer/engine.cc | 7 +-
gcc/analyzer/program-point.cc | 3 +-
gcc/analyzer/program-state.cc | 42 ++--
gcc/analyzer/program-state.h | 4 +
gcc/analyzer/ranges.cc | 5 +-
gcc/analyzer/region-model-manager.cc | 8 +-
gcc/analyzer/region-model-manager.h | 16 +-
gcc/analyzer/region-model.cc | 279 +++++++++++++------------
gcc/analyzer/region-model.h | 28 ++-
gcc/analyzer/region.cc | 2 +-
gcc/analyzer/sm-signal.cc | 2 +-
gcc/analyzer/state-purge.cc | 2 +-
gcc/analyzer/store.cc | 5 +-
gcc/analyzer/symbolic-nodes.cc | 24 +++
gcc/analyzer/symbolic-nodes.h | 35 ++++
19 files changed, 467 insertions(+), 297 deletions(-)
diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc
index 861823f6aea..f9822e856c4 100644
--- a/gcc/analyzer/access-diagram.cc
+++ b/gcc/analyzer/access-diagram.cc
@@ -2704,7 +2704,8 @@ assert_eq_typeless_integer (const location &loc,
static void
test_bit_size_expr_to_bytes ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
/* 40 bits: should be 5 bytes. */
{
diff --git a/gcc/analyzer/common.h b/gcc/analyzer/common.h
index 04abf1dd0ff..9f100068722 100644
--- a/gcc/analyzer/common.h
+++ b/gcc/analyzer/common.h
@@ -57,6 +57,7 @@ class superedge;
namespace symbolic
{
class node;
+ class node_manager;
}
class svalue;
@@ -120,6 +121,7 @@ class checker_event;
class checker_path;
class extrinsic_state;
class sm_state_map;
+class call_string;
class program_point;
class program_state;
class exploded_graph;
diff --git a/gcc/analyzer/constraint-manager.cc
b/gcc/analyzer/constraint-manager.cc
index 3293f21b324..4819c53e20f 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -3458,8 +3458,8 @@ test_constraint_conditions ()
/* Self-comparisons. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, x);
ASSERT_CONDITION_TRUE (model, x, LE_EXPR, x);
ASSERT_CONDITION_TRUE (model, x, GE_EXPR, x);
@@ -3470,23 +3470,23 @@ test_constraint_conditions ()
/* Adding self-equality shouldn't add equiv classes. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, x);
ADD_SAT_CONSTRAINT (model, int_42, EQ_EXPR, int_42);
/* ...even when done directly via svalues: */
const svalue *sval_int_42 = model.get_rvalue (int_42, nullptr);
bool sat = model.get_constraints ()->add_constraint (sval_int_42,
- EQ_EXPR,
- sval_int_42);
+ EQ_EXPR,
+ sval_int_42);
ASSERT_TRUE (sat);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 0);
}
/* x == y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
@@ -3517,8 +3517,8 @@ test_constraint_conditions ()
/* x == y, then y == z */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
@@ -3534,8 +3534,8 @@ test_constraint_conditions ()
/* x != y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, NE_EXPR, y);
@@ -3565,8 +3565,8 @@ test_constraint_conditions ()
/* x < y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, LT_EXPR, y);
@@ -3588,8 +3588,8 @@ test_constraint_conditions ()
/* x <= y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, LE_EXPR, y);
@@ -3611,8 +3611,8 @@ test_constraint_conditions ()
/* x > y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, GT_EXPR, y);
@@ -3634,8 +3634,8 @@ test_constraint_conditions ()
/* x >= y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, GE_EXPR, y);
@@ -3659,8 +3659,9 @@ test_constraint_conditions ()
/* Constants. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ASSERT_CONDITION_FALSE (model, int_0, EQ_EXPR, int_42);
ASSERT_CONDITION_TRUE (model, int_0, NE_EXPR, int_42);
ASSERT_CONDITION_TRUE (model, int_0, LT_EXPR, int_42);
@@ -3671,8 +3672,9 @@ test_constraint_conditions ()
/* x == 0, y == 42. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, int_42);
@@ -3688,48 +3690,54 @@ test_constraint_conditions ()
/* x == y && x != y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
ADD_UNSAT_CONSTRAINT (model, x, NE_EXPR, y);
}
/* x == 0 then x == 42. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
ADD_UNSAT_CONSTRAINT (model, x, EQ_EXPR, int_42);
}
/* x == 0 then x != 0. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
ADD_UNSAT_CONSTRAINT (model, x, NE_EXPR, int_0);
}
/* x == 0 then x > 0. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
ADD_UNSAT_CONSTRAINT (model, x, GT_EXPR, int_0);
}
/* x != y && x == y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, NE_EXPR, y);
ADD_UNSAT_CONSTRAINT (model, x, EQ_EXPR, y);
}
/* x <= y && x > y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, x, LE_EXPR, y);
ADD_UNSAT_CONSTRAINT (model, x, GT_EXPR, y);
}
@@ -3749,8 +3757,9 @@ test_transitivity ()
/* a == b, then c == d, then c == b. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, b);
ASSERT_CONDITION_UNKNOWN (model, b, EQ_EXPR, c);
ASSERT_CONDITION_UNKNOWN (model, c, EQ_EXPR, d);
@@ -3770,8 +3779,9 @@ test_transitivity ()
/* Transitivity: "a < b", "b < c" should imply "a < c". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
@@ -3781,8 +3791,9 @@ test_transitivity ()
/* Transitivity: "a <= b", "b < c" should imply "a < c". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, LE_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
@@ -3792,8 +3803,9 @@ test_transitivity ()
/* Transitivity: "a <= b", "b <= c" should imply "a <= c". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, LE_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, LE_EXPR, c);
@@ -3803,8 +3815,9 @@ test_transitivity ()
/* Transitivity: "a > b", "b > c" should imply "a > c". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
@@ -3814,8 +3827,9 @@ test_transitivity ()
/* Transitivity: "a >= b", "b > c" should imply " a > c". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
@@ -3825,8 +3839,9 @@ test_transitivity ()
/* Transitivity: "a >= b", "b >= c" should imply "a >= c". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, GE_EXPR, c);
@@ -3841,8 +3856,9 @@ test_transitivity ()
but also that:
(a < d). */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, b);
ADD_SAT_CONSTRAINT (model, c, LT_EXPR, d);
ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
@@ -3854,8 +3870,9 @@ test_transitivity ()
/* Transitivity: "a >= b", "b >= a" should imply that a == b. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, GE_EXPR, a);
@@ -3869,8 +3886,9 @@ test_transitivity ()
/* Transitivity: "a >= b", "b > a" should be impossible. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
ADD_UNSAT_CONSTRAINT (model, b, GT_EXPR, a);
}
@@ -3878,8 +3896,9 @@ test_transitivity ()
/* Transitivity: "a >= b", "b >= c", "c >= a" should imply
that a == b == c. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, GE_EXPR, c);
ADD_SAT_CONSTRAINT (model, c, GE_EXPR, a);
@@ -3890,8 +3909,9 @@ test_transitivity ()
/* Transitivity: "a > b", "b > c", "c > a"
should be impossible. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
ADD_UNSAT_CONSTRAINT (model, c, GT_EXPR, a);
@@ -3920,16 +3940,18 @@ test_constant_comparisons ()
/* Given a >= 1024, then a <= 1023 should be impossible. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_1024);
ADD_UNSAT_CONSTRAINT (model, a, LE_EXPR, int_1023);
}
/* a > 4. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_4);
ASSERT_CONDITION_TRUE (model, a, GT_EXPR, int_4);
ASSERT_CONDITION_TRUE (model, a, NE_EXPR, int_3);
@@ -3938,8 +3960,9 @@ test_constant_comparisons ()
/* a <= 4. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
ASSERT_CONDITION_FALSE (model, a, GT_EXPR, int_4);
ASSERT_CONDITION_FALSE (model, a, GT_EXPR, int_5);
@@ -3948,8 +3971,9 @@ test_constant_comparisons ()
/* If "a > b" and "a == 3", then "b == 4" ought to be unsatisfiable. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_3);
ADD_UNSAT_CONSTRAINT (model, b, EQ_EXPR, int_4);
@@ -3960,8 +3984,8 @@ test_constant_comparisons ()
/* If "a <= 4" && "a > 3", then "a == 4",
assuming a is of integral type. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
@@ -3970,8 +3994,8 @@ test_constant_comparisons ()
/* If "a > 3" && "a <= 4", then "a == 4",
assuming a is of integral type. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
@@ -3979,8 +4003,9 @@ test_constant_comparisons ()
/* If "a > 3" && "a < 5", then "a == 4",
assuming a is of integral type. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
@@ -3988,16 +4013,18 @@ test_constant_comparisons ()
/* If "a >= 4" && "a < 5", then "a == 4",
assuming a is of integral type. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_4);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
}
/* If "a >= 4" && "a <= 4", then "a == 4". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_4);
ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
@@ -4011,8 +4038,9 @@ test_constant_comparisons ()
tree float_3 = build_real_from_int_cst (double_type_node, int_3);
tree float_4 = build_real_from_int_cst (double_type_node, int_4);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, f, GT_EXPR, float_3);
ADD_SAT_CONSTRAINT (model, f, LE_EXPR, float_4);
ASSERT_CONDITION_UNKNOWN (model, f, EQ_EXPR, float_4);
@@ -4021,22 +4049,23 @@ test_constant_comparisons ()
/* "a > 3 && a <= 3" should be impossible. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
ADD_UNSAT_CONSTRAINT (model, a, LE_EXPR, int_3);
}
/* "(a + 1) > 3 && a < 3" should be impossible. */
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, a_plus_one, GT_EXPR, int_3);
ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_3);
}
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_3);
ADD_UNSAT_CONSTRAINT (model, a_plus_one, GT_EXPR, int_3);
}
@@ -4044,38 +4073,38 @@ test_constant_comparisons ()
/* "3 < a < 4" should be impossible for integer a. */
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
}
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, int_1, LT_EXPR, a);
ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
}
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, int_1, LT_EXPR, a);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
ADD_SAT_CONSTRAINT (model, int_3, LT_EXPR, a);
ADD_UNSAT_CONSTRAINT (model, a, LT_EXPR, int_4);
}
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_4);
ADD_UNSAT_CONSTRAINT (model, int_3, LT_EXPR, a);
}
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
ADD_UNSAT_CONSTRAINT (model, int_4, GT_EXPR, a);
}
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, int_4, GT_EXPR, a);
ADD_UNSAT_CONSTRAINT (model, a, GT_EXPR, int_3);
}
@@ -4097,8 +4126,8 @@ test_constraint_impl ()
/* x == y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
@@ -4110,8 +4139,9 @@ test_constraint_impl ()
/* y <= z; x == y. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
@@ -4132,8 +4162,9 @@ test_constraint_impl ()
/* y <= z; y == x. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
@@ -4154,8 +4185,8 @@ test_constraint_impl ()
/* x == 0, then x != 42. */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
ADD_SAT_CONSTRAINT (model, x, NE_EXPR, int_42);
@@ -4182,9 +4213,10 @@ test_equality ()
tree y = build_global_decl ("y", integer_type_node);
{
- region_model_manager mgr;
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ symbolic::node_manager node_mgr;
+
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
constraint_manager *cm0 = model0.get_constraints ();
constraint_manager *cm1 = model1.get_constraints ();
@@ -4202,7 +4234,7 @@ test_equality ()
ASSERT_NE (model0.hash (), model1.hash ());
ASSERT_NE (model0, model1);
- region_model model2 (&mgr);
+ region_model model2 (node_mgr);
constraint_manager *cm2 = model2.get_constraints ();
/* Make the same change to cm2. */
ADD_SAT_CONSTRAINT (model2, x, EQ_EXPR, y);
@@ -4219,11 +4251,12 @@ test_equality ()
static void
test_many_constants ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
program_point point (program_point::origin (mgr));
tree a = build_global_decl ("a", integer_type_node);
- region_model model (&mgr);
+ region_model model (node_mgr);
auto_vec<tree> constants;
for (int i = 0; i < 20; i++)
{
@@ -4234,7 +4267,7 @@ test_many_constants ()
/* Merge, and check the result. */
region_model other (model);
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model.can_merge_with_p (other, point, &merged));
model.canonicalize ();
merged.canonicalize ();
@@ -4257,8 +4290,9 @@ test_purging (void)
/* "a != 0". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, NE_EXPR, int_0);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 1);
@@ -4274,8 +4308,9 @@ test_purging (void)
/* "a != 0" && "b != 0". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, NE_EXPR, int_0);
ADD_SAT_CONSTRAINT (model, b, NE_EXPR, int_0);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 3);
@@ -4293,8 +4328,9 @@ test_purging (void)
/* "a != 0" && "b == 0". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, NE_EXPR, int_0);
ADD_SAT_CONSTRAINT (model, b, EQ_EXPR, int_0);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
@@ -4312,8 +4348,9 @@ test_purging (void)
/* "a == 0". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_0);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
ASSERT_EQ (model.get_constraints ()->m_constraints.length (), 0);
@@ -4329,8 +4366,9 @@ test_purging (void)
/* "a == 0" && "b != 0". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_0);
ADD_SAT_CONSTRAINT (model, b, NE_EXPR, int_0);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 2);
@@ -4348,8 +4386,9 @@ test_purging (void)
/* "a == 0" && "b == 0". */
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
+
ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_0);
ADD_SAT_CONSTRAINT (model, b, EQ_EXPR, int_0);
ASSERT_EQ (model.get_constraints ()->m_equiv_classes.length (), 1);
@@ -4683,7 +4722,7 @@ test_bounded_ranges ()
static void
test_bits (void)
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
tree int_0 = integer_zero_node;
tree int_0x80 = build_int_cst (integer_type_node, 0x80);
@@ -4695,7 +4734,7 @@ test_bits (void)
/* "x & 0x80 == 0x80". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0x80, EQ_EXPR, int_0x80);
ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0x80);
@@ -4703,7 +4742,7 @@ test_bits (void)
/* "x & 0x80 != 0x80". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0x80, NE_EXPR, int_0x80);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, int_0x80);
@@ -4711,7 +4750,7 @@ test_bits (void)
/* "x & 0x80 == 0". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0x80, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0);
@@ -4720,7 +4759,7 @@ test_bits (void)
/* "x & 0x80 != 0". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0x80, NE_EXPR, int_0);
ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0x80);
@@ -4730,7 +4769,7 @@ test_bits (void)
/* "x & 0xff == 0x80". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0xff, EQ_EXPR, int_0x80);
ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0x80);
@@ -4739,7 +4778,7 @@ test_bits (void)
/* "x & 0xff != 0x80". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0xff, NE_EXPR, int_0x80);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, int_0x80);
@@ -4748,7 +4787,7 @@ test_bits (void)
/* "x & 0xff == 0". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0xff, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0);
@@ -4758,7 +4797,7 @@ test_bits (void)
/* "x & 0xff != 0". */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x_bit_and_0xff, NE_EXPR, int_0);
ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, int_0x80);
diff --git a/gcc/analyzer/diagnostic-manager.cc
b/gcc/analyzer/diagnostic-manager.cc
index 2e7acba0910..053d8153ce3 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -1918,7 +1918,7 @@ diagnostic_manager::annotate_exploded_path (const
path_builder &pb,
idx,
eedge->m_src->m_index,
eedge->m_dest->m_index);
- region_model src_model (pb.get_ext_state ().get_model_manager ());
+ region_model src_model (pb.get_ext_state ().get_node_manager ());
if (idx > 0)
src_model = dst_models[idx - 1];
src_models.push_back (src_model);
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index a42350531b4..4856966c700 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -3976,7 +3976,7 @@ feasibility_problem::to_json () const
feasibility_state::feasibility_state (region_model_manager *manager,
const supergraph &sg)
-: m_model (manager),
+: m_model (manager->get_node_manager ()),
m_snodes_visited (sg.m_nodes.length ())
{
bitmap_clear (m_snodes_visited);
@@ -4975,7 +4975,8 @@ impl_run_checkers (logger *logger)
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
node->get_untransformed_body ();
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
/* Create the supergraph. */
supergraph sg (mgr, logger);
@@ -4986,7 +4987,7 @@ impl_run_checkers (logger *logger)
maybe_dump_supergraph (sg, "fixup-locations");
- engine eng (mgr, &sg);
+ engine eng (node_mgr, &sg);
state_purge_map *purge_map = nullptr;
if (flag_analyzer_state_purge)
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index 228c36070f8..79ba0442f3a 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -246,7 +246,8 @@ namespace selftest {
static void
test_program_point_equality ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const supernode *snode = nullptr;
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 1c1c58784f4..c549a8baff1 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -118,6 +118,13 @@ extrinsic_state::get_model_manager () const
return nullptr; /* for selftests. */
}
+symbolic::node_manager &
+extrinsic_state::get_node_manager () const
+{
+ gcc_assert (m_engine);
+ return m_engine->get_node_manager ();
+}
+
/* Try to find a state machine named NAME.
If found, return true and write its index to *OUT.
Otherwise return false. */
@@ -932,8 +939,8 @@ program_state::program_state (const extrinsic_state
&ext_state)
m_valid (true)
{
engine *eng = ext_state.get_engine ();
- region_model_manager *mgr = eng->get_model_manager ();
- m_region_model = new region_model (mgr);
+ auto &node_mgr = eng->get_node_manager ();
+ m_region_model = new region_model (node_mgr);
const int num_states = ext_state.get_num_checkers ();
for (int i = 0; i < num_states; i++)
{
@@ -1700,15 +1707,15 @@ test_sm_state_map ()
std::vector<std::unique_ptr<state_machine>> checkers;
const state_machine &borrowed_sm = *sm.get ();
checkers.push_back (std::move (sm));
- region_model_manager mgr;
- engine eng (mgr);
+ symbolic::node_manager node_mgr;
+ engine eng (node_mgr);
extrinsic_state ext_state (std::move (checkers), &eng);
/* Test setting states on svalue_id instances directly. */
{
const state_machine::state test_state_42 ("test state 42", 42);
const state_machine::state_t TEST_STATE_42 = &test_state_42;
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *x_sval = model.get_rvalue (x, nullptr);
const svalue *y_sval = model.get_rvalue (y, nullptr);
const svalue *z_sval = model.get_rvalue (z, nullptr);
@@ -1736,7 +1743,7 @@ test_sm_state_map ()
/* Test setting states via equivalence classes. */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *x_sval = model.get_rvalue (x, nullptr);
const svalue *y_sval = model.get_rvalue (y, nullptr);
const svalue *z_sval = model.get_rvalue (z, nullptr);
@@ -1759,7 +1766,7 @@ test_sm_state_map ()
/* Test equality and hashing. */
{
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *y_sval = model.get_rvalue (y, nullptr);
const svalue *z_sval = model.get_rvalue (z, nullptr);
@@ -1793,7 +1800,7 @@ test_sm_state_map ()
ASSERT_EQ (map0.hash (), map1.hash ());
ASSERT_EQ (map0, map1);
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *x_sval = model.get_rvalue (x, nullptr);
const svalue *y_sval = model.get_rvalue (y, nullptr);
const svalue *z_sval = model.get_rvalue (z, nullptr);
@@ -1826,8 +1833,9 @@ test_program_state_1 ()
const state_machine::state_t UNCHECKED_STATE
= sm->get_state_by_name ("unchecked");
- region_model_manager mgr;
- engine eng (mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ engine eng (node_mgr);
extrinsic_state ext_state (std::move (sm), &eng);
program_state s (ext_state);
region_model *model = s.m_region_model;
@@ -1856,8 +1864,8 @@ test_program_state_2 ()
tree string_cst_ptr = build_string_literal (4, "foo");
std::vector<std::unique_ptr<state_machine>> checkers;
- region_model_manager mgr;
- engine eng (mgr);
+ symbolic::node_manager node_mgr;
+ engine eng (node_mgr);
extrinsic_state ext_state (std::move (checkers), &eng);
program_state s (ext_state);
@@ -1877,8 +1885,9 @@ test_program_state_merging ()
malloc sm-state, pointing to a region on the heap. */
tree p = build_global_decl ("p", ptr_type_node);
- region_model_manager mgr;
- engine eng (mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ engine eng (node_mgr);
program_point point (program_point::origin (mgr));
extrinsic_state ext_state (make_malloc_state_machine (nullptr),
&eng);
@@ -1944,8 +1953,9 @@ test_program_state_merging ()
static void
test_program_state_merging_2 ()
{
- region_model_manager mgr;
- engine eng (mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ engine eng (node_mgr);
program_point point (program_point::origin (mgr));
extrinsic_state ext_state (make_signal_state_machine (nullptr), &eng);
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index e098d84a455..b8219158c11 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -73,6 +73,10 @@ public:
std::unique_ptr<json::object> to_json () const;
engine *get_engine () const { return m_engine; }
+
+ symbolic::node_manager &
+ get_node_manager () const;
+
region_model_manager *get_model_manager () const;
bool get_sm_idx_by_name (const char *name, unsigned *out) const;
diff --git a/gcc/analyzer/ranges.cc b/gcc/analyzer/ranges.cc
index 241d7bfd07d..d5977b60784 100644
--- a/gcc/analyzer/ranges.cc
+++ b/gcc/analyzer/ranges.cc
@@ -232,8 +232,9 @@ namespace selftest {
static void test_intersects (void)
{
- region_model_manager mgr;
- region_model m (&mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ region_model m (node_mgr);
/* Test various concrete ranges. */
symbolic_byte_offset zero (0, mgr);
diff --git a/gcc/analyzer/region-model-manager.cc
b/gcc/analyzer/region-model-manager.cc
index fd5d91c8ee4..1a7bfc22572 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -42,9 +42,10 @@ namespace ana {
/* region_model_manager's ctor. */
-region_model_manager::region_model_manager (logger *logger)
-: m_logger (logger),
- m_next_node_id (0),
+region_model_manager::region_model_manager (symbolic::node_manager &node_mgr,
+ logger *logger)
+: m_node_mgr (node_mgr),
+ m_logger (logger),
m_empty_call_string (),
m_root_region (alloc_node_id ()),
m_stack_region (alloc_node_id (), &m_root_region),
@@ -2158,7 +2159,6 @@ region_model_manager::log_stats (logger *logger, bool
show_objs) const
LOG_SCOPE (logger);
logger->log ("call string consolidation");
m_empty_call_string.recursive_log (logger);
- logger->log ("next node id: %i", m_next_node_id);
logger->log ("svalue consolidation");
log_uniq_map (logger, show_objs, "constant_svalue", m_constants_map);
log_uniq_map (logger, show_objs, "unknown_svalue", m_unknowns_map);
diff --git a/gcc/analyzer/region-model-manager.h
b/gcc/analyzer/region-model-manager.h
index 6e6cbe74700..fd4ff449344 100644
--- a/gcc/analyzer/region-model-manager.h
+++ b/gcc/analyzer/region-model-manager.h
@@ -31,11 +31,12 @@ namespace ana {
class region_model_manager
{
public:
- region_model_manager (logger *logger = nullptr);
+ region_model_manager (symbolic::node_manager &node_mgr,
+ logger *logger = nullptr);
~region_model_manager ();
- unsigned get_num_nodes () const { return m_next_node_id; }
- unsigned alloc_node_id () { return m_next_node_id++; }
+ unsigned
+ alloc_node_id () { return m_node_mgr.alloc_node_id (); }
/* call_string consolidation. */
const call_string &get_empty_call_string () const
@@ -153,6 +154,12 @@ public:
tree t,
const dump_location_t &loc);
+ symbolic::node_manager &
+ get_node_manager () const
+ {
+ return m_node_mgr;
+ }
+
store_manager *get_store_manager () { return &m_store_mgr; }
bounded_ranges_manager *get_range_manager () const { return m_range_mgr; }
@@ -203,10 +210,9 @@ private:
const svalue *maybe_fold_asm_output_svalue (tree type,
const vec<const svalue *>
&inputs);
+ symbolic::node_manager &m_node_mgr;
logger *m_logger;
- unsigned m_next_node_id;
-
const call_string m_empty_call_string;
root_region m_root_region;
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 60e80a9e69e..1e7b84134ea 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -408,19 +408,24 @@ exception_node::add_to_reachable_regions
(reachable_regions ®s) const
/* Ctor for region_model: construct an "empty" model. */
-region_model::region_model (region_model_manager *mgr)
-: m_mgr (mgr), m_store (), m_current_frame (nullptr),
+region_model::region_model (symbolic::node_manager &node_mgr)
+: m_node_mgr (node_mgr),
+ m_mgr (&node_mgr.get_region_model_manager ()),
+ m_store (),
+ m_current_frame (nullptr),
m_thrown_exceptions_stack (),
m_caught_exceptions_stack (),
m_dynamic_extents ()
{
- m_constraints = new constraint_manager (mgr);
+ m_constraints = new constraint_manager (m_mgr);
}
/* region_model's copy ctor. */
region_model::region_model (const region_model &other)
-: m_mgr (other.m_mgr), m_store (other.m_store),
+: m_node_mgr (other.m_node_mgr),
+ m_mgr (other.m_mgr),
+ m_store (other.m_store),
m_constraints (new constraint_manager (*other.m_constraints)),
m_current_frame (other.m_current_frame),
m_thrown_exceptions_stack (other.m_thrown_exceptions_stack),
@@ -7567,9 +7572,9 @@ rejected_ranges_constraint::to_json () const
/* engine's ctor. */
-engine::engine (region_model_manager &mgr,
+engine::engine (symbolic::node_manager &node_mgr,
const supergraph *sg)
-: m_mgr (mgr),
+: m_node_mgr (node_mgr),
m_sg (sg)
{
}
@@ -7579,7 +7584,7 @@ engine::engine (region_model_manager &mgr,
void
engine::log_stats (logger *logger) const
{
- m_mgr.log_stats (logger, true);
+ m_node_mgr.log_stats (logger, true);
}
namespace ana {
@@ -7711,8 +7716,8 @@ assert_dump_eq (const location &loc,
static void
test_dump ()
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ASSERT_DUMP_EQ (model, false,
"stack depth: 0\n"
@@ -7802,8 +7807,9 @@ test_struct ()
tree int_17 = build_int_cst (integer_type_node, 17);
tree int_m3 = build_int_cst (integer_type_node, -3);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ region_model model (node_mgr);
/* Set fields in order y, then x. */
model.set_value (c_y, int_m3, nullptr);
model.set_value (c_x, int_17, nullptr);
@@ -7856,8 +7862,8 @@ test_array_1 ()
tree a = build_global_decl ("a", arr_type);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
tree int_0 = integer_zero_node;
tree a_0 = build4 (ARRAY_REF, char_type_node,
a, int_0, NULL_TREE, NULL_TREE);
@@ -7870,12 +7876,12 @@ test_array_1 ()
static void
test_get_representative_tree ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
/* STRING_CST. */
{
tree string_cst = build_string (4, "foo");
- region_model m (&mgr);
+ region_model m (node_mgr);
const svalue *str_sval = m.get_rvalue (string_cst, nullptr);
tree rep = m.get_representative_tree (str_sval);
ASSERT_EQ (rep, string_cst);
@@ -7884,7 +7890,7 @@ test_get_representative_tree ()
/* String literal. */
{
tree string_cst_ptr = build_string_literal (4, "foo");
- region_model m (&mgr);
+ region_model m (node_mgr);
const svalue *str_sval = m.get_rvalue (string_cst_ptr, nullptr);
tree rep = m.get_representative_tree (str_sval);
ASSERT_DUMP_TREE_EQ (rep, "&\"foo\"[0]");
@@ -7895,13 +7901,13 @@ test_get_representative_tree ()
tree tlen = size_int (10);
tree arr_type = build_array_type (char_type_node, build_index_type (tlen));
tree a = build_global_decl ("a", arr_type);
- placeholder_svalue test_sval (mgr.alloc_node_id (),
+ placeholder_svalue test_sval (node_mgr.alloc_node_id (),
char_type_node, "test value");
/* Value of a[3]. */
{
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
tree int_3 = build_int_cst (integer_type_node, 3);
tree a_3 = build4 (ARRAY_REF, char_type_node,
a, int_3, NULL_TREE, NULL_TREE);
@@ -7914,7 +7920,7 @@ test_get_representative_tree ()
/* Value of a[0]. */
{
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
tree idx = integer_zero_node;
tree a_0 = build4 (ARRAY_REF, char_type_node,
a, idx, NULL_TREE, NULL_TREE);
@@ -7939,9 +7945,9 @@ test_get_representative_tree ()
/* Value of initial field. */
{
- region_model m (&mgr);
+ region_model m (node_mgr);
const region *c_x_reg = m.get_lvalue (c_x, &ctxt);
- placeholder_svalue test_sval_x (mgr.alloc_node_id (),
+ placeholder_svalue test_sval_x (node_mgr.alloc_node_id (),
integer_type_node, "test x val");
m.set_value (c_x_reg, &test_sval_x, &ctxt);
tree rep = m.get_representative_tree (&test_sval_x);
@@ -7950,9 +7956,9 @@ test_get_representative_tree ()
/* Value of non-initial field. */
{
- region_model m (&mgr);
+ region_model m (node_mgr);
const region *c_y_reg = m.get_lvalue (c_y, &ctxt);
- placeholder_svalue test_sval_y (mgr.alloc_node_id (),
+ placeholder_svalue test_sval_y (node_mgr.alloc_node_id (),
integer_type_node, "test y val");
m.set_value (c_y_reg, &test_sval_y, &ctxt);
tree rep = m.get_representative_tree (&test_sval_y);
@@ -7971,8 +7977,8 @@ test_unique_constants ()
tree int_42 = build_int_cst (integer_type_node, 42);
test_region_model_context ctxt;
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ASSERT_EQ (model.get_rvalue (int_0, &ctxt), model.get_rvalue (int_0, &ctxt));
ASSERT_EQ (model.get_rvalue (int_42, &ctxt),
model.get_rvalue (int_42, &ctxt));
@@ -7999,7 +8005,8 @@ test_unique_constants ()
static void
test_unique_unknowns ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const svalue *unknown_int
= mgr.get_or_create_unknown_svalue (integer_type_node);
/* Repeated calls with the same type should get the same "unknown"
@@ -8024,12 +8031,13 @@ test_unique_unknowns ()
static void
test_initial_svalue_folding ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
tree x = build_global_decl ("x", integer_type_node);
tree y = build_global_decl ("y", integer_type_node);
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *x_init = model.get_rvalue (x, &ctxt);
const svalue *y_init = model.get_rvalue (y, &ctxt);
ASSERT_NE (x_init, y_init);
@@ -8043,12 +8051,14 @@ test_initial_svalue_folding ()
static void
test_unaryop_svalue_folding ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+
tree x = build_global_decl ("x", integer_type_node);
tree y = build_global_decl ("y", integer_type_node);
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *x_init = model.get_rvalue (x, &ctxt);
const svalue *y_init = model.get_rvalue (y, &ctxt);
const region *x_reg = model.get_lvalue (x, &ctxt);
@@ -8083,7 +8093,8 @@ test_binop_svalue_folding ()
{
#define NUM_CSTS 10
tree cst_int[NUM_CSTS];
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const svalue *cst_sval[NUM_CSTS];
for (int i = 0; i < NUM_CSTS; i++)
{
@@ -8131,7 +8142,7 @@ test_binop_svalue_folding ()
tree x = build_global_decl ("x", integer_type_node);
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *x_init = model.get_rvalue (x, &ctxt);
/* PLUS_EXPR folding. */
@@ -8236,8 +8247,9 @@ test_sub_svalue_folding ()
tree c_x = build3 (COMPONENT_REF, TREE_TYPE (ct.m_x_field),
c, ct.m_x_field, NULL_TREE);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ region_model model (node_mgr);
test_region_model_context ctxt;
const region *c_x_reg = model.get_lvalue (c_x, &ctxt);
@@ -8270,7 +8282,8 @@ get_bit (region_model_manager *mgr,
static void
test_bits_within_svalue_folding ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const svalue *zero = mgr.get_or_create_int_cst (boolean_type_node, 0);
const svalue *one = mgr.get_or_create_int_cst (boolean_type_node, 1);
@@ -8307,7 +8320,8 @@ test_bits_within_svalue_folding ()
static void
test_descendent_of_p ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const region *stack = mgr.get_stack_region ();
const region *heap = mgr.get_heap_region ();
const region *code = mgr.get_code_region ();
@@ -8334,7 +8348,8 @@ static void
test_bit_range_regions ()
{
tree x = build_global_decl ("x", integer_type_node);
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const region *x_reg = mgr.get_region_for_global (x);
const region *byte0
= mgr.get_bit_range (x_reg, char_type_node, bit_range (0, 8));
@@ -8355,8 +8370,8 @@ test_assignment ()
tree y = build_global_decl ("y", integer_type_node);
/* "x == 0", then use of y, then "y = 0;". */
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, int_0);
model.set_value (model.get_lvalue (y, nullptr),
@@ -8387,8 +8402,8 @@ test_compound_assignment ()
tree int_17 = build_int_cst (integer_type_node, 17);
tree int_m3 = build_int_cst (integer_type_node, -3);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
model.set_value (c_x, int_17, nullptr);
model.set_value (c_y, int_m3, nullptr);
@@ -8447,9 +8462,10 @@ test_stack_frames ()
/* "q" global. */
tree q = build_global_decl ("q", ptr_type_node);
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
/* Push stack frame for "parent_fn". */
const region *parent_frame_reg
@@ -8553,9 +8569,10 @@ test_get_representative_path_var ()
integer_type_node);
DECL_CONTEXT (n) = fndecl;
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
/* Push 5 stack frames for "factorial", each with a param */
auto_vec<const region *> parm_regs;
@@ -8608,9 +8625,9 @@ test_equality_1 ()
tree int_17 = build_int_cst (integer_type_node, 17);
/* Verify that "empty" region_model instances are equal to each other. */
- region_model_manager mgr;
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
ASSERT_EQ (model0, model1);
/* Verify that setting state in model1 makes the models non-equal. */
@@ -8647,8 +8664,8 @@ test_canonicalization_2 ()
tree x = build_global_decl ("x", integer_type_node);
tree y = build_global_decl ("y", integer_type_node);
- region_model_manager mgr;
- region_model model0 (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model0 (node_mgr);
model0.set_value (model0.get_lvalue (x, nullptr),
model0.get_rvalue (int_42, nullptr),
nullptr);
@@ -8656,7 +8673,7 @@ test_canonicalization_2 ()
model0.get_rvalue (int_113, nullptr),
nullptr);
- region_model model1 (&mgr);
+ region_model model1 (node_mgr);
model1.set_value (model1.get_lvalue (y, nullptr),
model1.get_rvalue (int_113, nullptr),
nullptr);
@@ -8681,12 +8698,12 @@ test_canonicalization_3 ()
tree x = build_global_decl ("x", integer_type_node);
tree y = build_global_decl ("y", integer_type_node);
- region_model_manager mgr;
- region_model model0 (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model0 (node_mgr);
model0.add_constraint (x, GT_EXPR, int_3, nullptr);
model0.add_constraint (y, GT_EXPR, int_42, nullptr);
- region_model model1 (&mgr);
+ region_model model1 (node_mgr);
model1.add_constraint (y, GT_EXPR, int_42, nullptr);
model1.add_constraint (x, GT_EXPR, int_3, nullptr);
@@ -8704,8 +8721,8 @@ test_canonicalization_4 ()
auto_vec<tree> csts;
append_interesting_constants (&csts);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
for (tree cst : csts)
model.get_rvalue (cst, nullptr);
@@ -8726,10 +8743,11 @@ assert_region_models_merge (tree expr, tree val_a, tree
val_b,
const svalue **out_merged_svalue)
{
region_model_manager *mgr = out_merged_model->get_manager ();
+ auto &node_mgr = mgr->get_node_manager ();
program_point point (program_point::origin (*mgr));
test_region_model_context ctxt;
- region_model model0 (mgr);
- region_model model1 (mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
if (val_a)
model0.set_value (model0.get_lvalue (expr, &ctxt),
model0.get_rvalue (val_a, &ctxt),
@@ -8776,13 +8794,14 @@ test_state_merging ()
ptr_type_node);
DECL_CONTEXT (q) = test_fndecl;
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
program_point point (program_point::origin (mgr));
{
- region_model model0 (&mgr);
- region_model model1 (&mgr);
- region_model merged (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
+ region_model merged (node_mgr);
/* Verify empty models can be merged. */
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (model0, merged);
@@ -8793,9 +8812,9 @@ test_state_merging ()
/* TODO: verify that the merged model doesn't have a value for
the global */
{
- region_model model0 (&mgr);
- region_model model1 (&mgr);
- region_model merged (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
+ region_model merged (node_mgr);
test_region_model_context ctxt;
model0.add_constraint (x, EQ_EXPR, int_42, &ctxt);
model1.add_constraint (x, EQ_EXPR, int_113, &ctxt);
@@ -8807,8 +8826,8 @@ test_state_merging ()
/* Verify handling of a PARM_DECL. */
{
test_region_model_context ctxt;
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
ASSERT_EQ (model0.get_stack_depth (), 0);
model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl),
nullptr, nullptr, &ctxt);
@@ -8823,7 +8842,7 @@ test_state_merging ()
ASSERT_EQ (model0, model1);
/* They should be mergeable, and the result should be the same. */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (model0, merged);
/* In particular, "a" should have the placeholder value. */
@@ -8833,8 +8852,8 @@ test_state_merging ()
/* Verify handling of a global. */
{
test_region_model_context ctxt;
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
placeholder_svalue test_sval (mgr.alloc_node_id (),
integer_type_node, "test sval");
@@ -8843,7 +8862,7 @@ test_state_merging ()
ASSERT_EQ (model0, model1);
/* They should be mergeable, and the result should be the same. */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (model0, merged);
/* In particular, "x" should have the placeholder value. */
@@ -8854,7 +8873,7 @@ test_state_merging ()
/* Two equal constant values. */
{
- region_model merged (&mgr);
+ region_model merged (node_mgr);
const svalue *merged_x_sval;
assert_region_models_merge (x, int_42, int_42, &merged, &merged_x_sval);
@@ -8866,7 +8885,7 @@ test_state_merging ()
/* Two non-equal constant values. */
{
- region_model merged (&mgr);
+ region_model merged (node_mgr);
const svalue *merged_x_sval;
assert_region_models_merge (x, int_42, int_113, &merged, &merged_x_sval);
@@ -8876,7 +8895,7 @@ test_state_merging ()
/* Initial and constant. */
{
- region_model merged (&mgr);
+ region_model merged (node_mgr);
const svalue *merged_x_sval;
assert_region_models_merge (x, NULL_TREE, int_113, &merged,
&merged_x_sval);
@@ -8886,7 +8905,7 @@ test_state_merging ()
/* Constant and initial. */
{
- region_model merged (&mgr);
+ region_model merged (node_mgr);
const svalue *merged_x_sval;
assert_region_models_merge (x, int_42, NULL_TREE, &merged, &merged_x_sval);
@@ -8905,7 +8924,7 @@ test_state_merging ()
/* Pointers: non-NULL and non-NULL: ptr to a local. */
{
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl),
nullptr, nullptr, nullptr);
model0.set_value (model0.get_lvalue (p, nullptr),
@@ -8915,14 +8934,14 @@ test_state_merging ()
ASSERT_EQ (model0, model1);
/* They should be mergeable, and the result should be the same. */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (model0, merged);
}
/* Pointers: non-NULL and non-NULL: ptr to a global. */
{
- region_model merged (&mgr);
+ region_model merged (node_mgr);
/* p == &y in both input models. */
const svalue *merged_p_sval;
assert_region_models_merge (p, addr_of_y, addr_of_y, &merged,
@@ -8939,13 +8958,13 @@ test_state_merging ()
/* Pointers: non-NULL ptrs to different globals should not merge;
see e.g. gcc.dg/analyzer/torture/uninit-pr108725.c */
{
- region_model merged_model (&mgr);
+ region_model merged_model (node_mgr);
program_point point (program_point::origin (mgr));
test_region_model_context ctxt;
/* x == &y vs x == &z in the input models; these are actually casts
of the ptrs to "int". */
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
model0.set_value (model0.get_lvalue (x, &ctxt),
model0.get_rvalue (addr_of_y, &ctxt),
&ctxt);
@@ -8959,7 +8978,7 @@ test_state_merging ()
/* Pointers: non-NULL and non-NULL: ptr to a heap region. */
{
test_region_model_context ctxt;
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
tree size = build_int_cst (size_type_node, 1024);
const svalue *size_sval = mgr.get_or_create_constant_svalue (size);
const region *new_reg
@@ -8972,7 +8991,7 @@ test_state_merging ()
ASSERT_EQ (model0, model1);
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
/* The merged model ought to be identical. */
@@ -8983,7 +9002,7 @@ test_state_merging ()
it after self-merger. */
{
test_region_model_context ctxt;
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
placeholder_svalue placeholder_sval (mgr.alloc_node_id (),
integer_type_node, "test");
model0.set_value (model0.get_lvalue (x, &ctxt),
@@ -8992,7 +9011,7 @@ test_state_merging ()
region_model model1 (model0);
/* They should be mergeable, and the result should be the same. */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (model0, merged);
@@ -9002,23 +9021,23 @@ test_state_merging ()
}
{
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
test_region_model_context ctxt;
model0.add_constraint (x, EQ_EXPR, int_42, &ctxt);
model1.add_constraint (x, NE_EXPR, int_42, &ctxt);
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
}
{
- region_model model0 (&mgr);
- region_model model1 (&mgr);
+ region_model model0 (node_mgr);
+ region_model model1 (node_mgr);
test_region_model_context ctxt;
model0.add_constraint (x, EQ_EXPR, int_42, &ctxt);
model1.add_constraint (x, NE_EXPR, int_42, &ctxt);
model1.add_constraint (x, EQ_EXPR, int_113, &ctxt);
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
}
@@ -9034,7 +9053,7 @@ test_state_merging ()
/* Views. */
{
test_region_model_context ctxt;
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
const region *x_reg = model0.get_lvalue (x, &ctxt);
const region *x_as_ptr = mgr.get_cast_region (x_reg, ptr_type_node);
@@ -9044,14 +9063,14 @@ test_state_merging ()
ASSERT_EQ (model1, model0);
/* They should be mergeable, and the result should be the same. */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
}
/* Verify that we can merge a model in which a local in an older stack
frame points to a local in a more recent stack frame. */
{
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl),
nullptr, nullptr, nullptr);
const region *q_in_first_frame = model0.get_lvalue (q, nullptr);
@@ -9077,7 +9096,7 @@ test_state_merging ()
/* They should be mergeable, and the result should be the same
(after canonicalization, at least). */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
merged.canonicalize ();
ASSERT_EQ (model0, merged);
@@ -9085,7 +9104,7 @@ test_state_merging ()
/* Verify that we can merge a model in which a local points to a global. */
{
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
model0.push_frame (*DECL_STRUCT_FUNCTION (test_fndecl),
nullptr, nullptr, nullptr);
model0.set_value (model0.get_lvalue (q, nullptr),
@@ -9096,7 +9115,7 @@ test_state_merging ()
/* They should be mergeable, and the result should be the same
(after canonicalization, at least). */
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (model0, merged);
}
@@ -9115,17 +9134,18 @@ test_constraint_merging ()
tree z = build_global_decl ("z", integer_type_node);
tree n = build_global_decl ("n", integer_type_node);
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
test_region_model_context ctxt;
/* model0: 0 <= (x == y) < n. */
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
model0.add_constraint (x, EQ_EXPR, y, &ctxt);
model0.add_constraint (x, GE_EXPR, int_0, nullptr);
model0.add_constraint (x, LT_EXPR, n, nullptr);
/* model1: z != 5 && (0 <= x < n). */
- region_model model1 (&mgr);
+ region_model model1 (node_mgr);
model1.add_constraint (z, NE_EXPR, int_5, nullptr);
model1.add_constraint (x, GE_EXPR, int_0, nullptr);
model1.add_constraint (x, LT_EXPR, n, nullptr);
@@ -9133,7 +9153,7 @@ test_constraint_merging ()
/* They should be mergeable; the merged constraints should
be: (0 <= x < n). */
program_point point (program_point::origin (mgr));
- region_model merged (&mgr);
+ region_model merged (node_mgr);
ASSERT_TRUE (model0.can_merge_with_p (model1, point, &merged));
ASSERT_EQ (merged.eval_condition (x, GE_EXPR, int_0, &ctxt),
@@ -9153,7 +9173,8 @@ test_constraint_merging ()
static void
test_widening_constraints ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
const supernode *snode = nullptr;
tree int_0 = integer_zero_node;
tree int_m1 = build_int_cst (integer_type_node, -1);
@@ -9268,7 +9289,8 @@ test_widening_constraints ()
static void
test_iteration_1 ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
program_point point (program_point::origin (mgr));
tree int_0 = integer_zero_node;
@@ -9279,15 +9301,15 @@ test_iteration_1 ()
test_region_model_context ctxt;
/* model0: i: 0. */
- region_model model0 (&mgr);
+ region_model model0 (node_mgr);
model0.set_value (i, int_0, &ctxt);
/* model1: i: 1. */
- region_model model1 (&mgr);
+ region_model model1 (node_mgr);
model1.set_value (i, int_1, &ctxt);
/* Should merge "i" to a widened value. */
- region_model model2 (&mgr);
+ region_model model2 (node_mgr);
ASSERT_TRUE (model1.can_merge_with_p (model0, point, &model2));
const svalue *merged_i = model2.get_rvalue (i, &ctxt);
ASSERT_EQ (merged_i->get_kind (), SK_WIDENING);
@@ -9302,7 +9324,7 @@ test_iteration_1 ()
tristate (tristate::TS_TRUE));
/* Try merging with the initial state. */
- region_model model3 (&mgr);
+ region_model model3 (node_mgr);
ASSERT_TRUE (model2.can_merge_with_p (model0, point, &model3));
/* Merging the merged value with the initial value should be idempotent,
so that the analysis converges. */
@@ -9323,7 +9345,7 @@ test_iteration_1 ()
ASSERT_EQ (plus_one->get_kind (), SK_BINOP);
/* Try merging with the "i: 1" state. */
- region_model model5 (&mgr);
+ region_model model5 (node_mgr);
ASSERT_TRUE (model4.can_merge_with_p (model1, point, &model5));
ASSERT_EQ (model5.get_rvalue (i, &ctxt), plus_one);
ASSERT_EQ (model5, model4);
@@ -9331,7 +9353,7 @@ test_iteration_1 ()
/* "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_model model6 (&mgr);
+ region_model model6 (node_mgr);
ASSERT_TRUE (model5.can_merge_with_p (model2, point, &model6));
const svalue *merged_widening = model6.get_rvalue (i, &ctxt);
ASSERT_EQ (merged_widening->get_kind (), SK_WIDENING);
@@ -9343,8 +9365,9 @@ test_iteration_1 ()
static void
test_malloc_constraints ()
{
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ region_model model (node_mgr);
tree p = build_global_decl ("p", ptr_type_node);
tree char_star = build_pointer_type (char_type_node);
tree q = build_global_decl ("q", char_star);
@@ -9382,8 +9405,9 @@ test_var ()
tree int_17 = build_int_cst (integer_type_node, 17);
tree int_m3 = build_int_cst (integer_type_node, -3);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ region_model model (node_mgr);
const region *i_reg = model.get_lvalue (i, nullptr);
ASSERT_EQ (i_reg->get_kind (), RK_DECL);
@@ -9439,8 +9463,9 @@ test_array_2 ()
tree int_42 = build_int_cst (integer_type_node, 42);
tree int_m3 = build_int_cst (integer_type_node, -3);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+ region_model model (node_mgr);
/* "arr[0] = 17;". */
model.set_value (arr_0, int_17, nullptr);
/* "arr[1] = -3;". */
@@ -9515,8 +9540,8 @@ test_mem_ref ()
tree offset_0 = build_int_cst (ptype, 0);
tree star_p = build2 (MEM_REF, integer_type_node, p, offset_0);
- region_model_manager mgr;
- region_model model (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model model (node_mgr);
/* "x = 17;". */
model.set_value (x, int_17, nullptr);
@@ -9566,8 +9591,8 @@ test_POINTER_PLUS_EXPR_then_MEM_REF ()
tree offset_0 = build_int_cst (ptype, 0);
tree mem_ref = build2 (MEM_REF, integer_type_node,
pointer_plus_expr, offset_0);
- region_model_manager mgr;
- region_model m (&mgr);
+ symbolic::node_manager node_mgr;
+ region_model m (node_mgr);
tree int_42 = build_int_cst (integer_type_node, 42);
m.set_value (mem_ref, int_42, nullptr);
@@ -9585,14 +9610,15 @@ test_malloc ()
tree n_times_4 = build2 (MULT_EXPR, size_type_node,
n, build_int_cst (size_type_node, 4));
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
/* "p = malloc (n * 4);". */
const svalue *size_sval = model.get_rvalue (n_times_4, &ctxt);
const region *reg
= model.get_or_create_region_for_heap_alloc (size_sval, &ctxt);
+ auto &mgr = node_mgr.get_region_model_manager ();
const svalue *ptr = mgr.get_ptr_svalue (int_star, reg);
model.set_value (model.get_lvalue (p, &ctxt), ptr, &ctxt);
ASSERT_EQ (model.get_capacity (reg), size_sval);
@@ -9616,9 +9642,10 @@ test_alloca ()
tree n_times_4 = build2 (MULT_EXPR, size_type_node,
n, build_int_cst (size_type_node, 4));
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
/* Push stack frame. */
const region *frame_reg
@@ -9643,13 +9670,15 @@ test_alloca ()
static void
test_involves_p ()
{
- region_model_manager mgr;
+ symbolic::node_manager node_mgr;
+ auto &mgr = node_mgr.get_region_model_manager ();
+
tree int_star = build_pointer_type (integer_type_node);
tree p = build_global_decl ("p", int_star);
tree q = build_global_decl ("q", int_star);
test_region_model_context ctxt;
- region_model model (&mgr);
+ region_model model (node_mgr);
const svalue *p_init = model.get_rvalue (p, &ctxt);
const svalue *q_init = model.get_rvalue (q, &ctxt);
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 90aed12d076..097758c6860 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -295,7 +295,7 @@ class region_model
public:
typedef region_to_value_map dynamic_extents_t;
- region_model (region_model_manager *mgr);
+ region_model (symbolic::node_manager &node_mgr);
region_model (const region_model &other);
~region_model ();
region_model &operator= (const region_model &other);
@@ -491,10 +491,11 @@ class region_model
region_model_context *ctxt);
void unset_dynamic_extents (const region *reg);
+ symbolic::node_manager &get_node_manager () const { return m_node_mgr; }
region_model_manager *get_manager () const { return m_mgr; }
bounded_ranges_manager *get_range_manager () const
{
- return m_mgr->get_range_manager ();
+ return get_manager ()->get_range_manager ();
}
void unbind_region_and_descendents (const region *reg,
@@ -724,6 +725,9 @@ private:
region_model_context *ctxt);
/* Storing this here to avoid passing it around everywhere. */
+ symbolic::node_manager &m_node_mgr;
+
+ // TODO: eliminate this copy (kept here to minimize churn)
region_model_manager *const m_mgr;
store m_store;
@@ -1326,19 +1330,31 @@ private:
class engine
{
public:
- engine (region_model_manager &mgr,
+ engine (symbolic::node_manager &node_mgr,
const supergraph *sg = nullptr);
const supergraph *get_supergraph () { return m_sg; }
- region_model_manager *get_model_manager () { return &m_mgr; }
+
+ symbolic::node_manager &
+ get_node_manager ()
+ {
+ return m_node_mgr;
+ }
+
+ region_model_manager *
+ get_model_manager ()
+ {
+ return &m_node_mgr.get_region_model_manager ();
+ }
+
known_function_manager *get_known_function_manager ()
{
- return m_mgr.get_known_function_manager ();
+ return get_model_manager ()->get_known_function_manager ();
}
void log_stats (logger *logger) const;
private:
- region_model_manager &m_mgr;
+ symbolic::node_manager &m_node_mgr;
const supergraph *m_sg;
};
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 4bb96119c93..974094d7251 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -1913,7 +1913,7 @@ decl_region::get_svalue_for_initializer
(region_model_manager *mgr) const
return get_svalue_for_constructor (init, mgr);
/* Reuse the get_rvalue logic from region_model. */
- region_model m (mgr);
+ region_model m (mgr->get_node_manager ());
return m.get_rvalue (path_var (init, 0), nullptr);
}
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index 08a0a2ad5eb..b4ebcc99051 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -194,7 +194,7 @@ update_model_for_signal_handler (region_model *model,
{
gcc_assert (model);
/* Purge all state within MODEL. */
- *model = region_model (model->get_manager ());
+ *model = region_model (model->get_node_manager ());
model->push_frame (handler_fun, nullptr, nullptr, nullptr);
}
diff --git a/gcc/analyzer/state-purge.cc b/gcc/analyzer/state-purge.cc
index 6b2f7996de5..e5c7593eaf9 100644
--- a/gcc/analyzer/state-purge.cc
+++ b/gcc/analyzer/state-purge.cc
@@ -538,7 +538,7 @@ state_purge_per_decl::process_worklists (const
state_purge_map &map,
for (auto iter : m_snodes_needing_decl)
worklist.safe_push (iter);
- region_model model (mgr);
+ region_model model (mgr->get_node_manager ());
model.push_frame (get_function (), nullptr, nullptr, nullptr);
/* Process worklist by walking backwards until we reach a stmt
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 66cfd3ddddf..ce6797664b5 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -1325,7 +1325,7 @@ static const svalue *
get_svalue_for_ctor_val (tree val, region_model_manager *mgr)
{
/* Reuse the get_rvalue logic from region_model. */
- region_model m (mgr);
+ region_model m (mgr->get_node_manager ());
return m.get_rvalue (path_var (val, 0), nullptr);
}
@@ -4403,7 +4403,8 @@ test_binding_key_overlap ()
static void
test_binding_map_ops ()
{
- region_model_manager region_mgr;
+ symbolic::node_manager node_mgr;
+ auto ®ion_mgr = node_mgr.get_region_model_manager ();
store_manager store_mgr (®ion_mgr);
/* Assignment of empty. */
diff --git a/gcc/analyzer/symbolic-nodes.cc b/gcc/analyzer/symbolic-nodes.cc
index 2c45feb5144..1c17a8d08d3 100644
--- a/gcc/analyzer/symbolic-nodes.cc
+++ b/gcc/analyzer/symbolic-nodes.cc
@@ -21,6 +21,9 @@ along with GCC; see the file COPYING3. If not see
#include "analyzer/common.h"
#include "analyzer/symbolic-nodes.h"
+#include "analyzer/analyzer-logging.h"
+#include "analyzer/region-model.h"
+#include "analyzer/region-model-manager.h"
#if ENABLE_ANALYZER
@@ -34,6 +37,27 @@ symbolic::node::cmp_ids (const symbolic::node *n1, const
symbolic::node *n2)
return (long)n1->get_id () - (long)n2->get_id ();
}
+// class node_manager
+
+symbolic::node_manager::node_manager ()
+: m_next_node_id (0),
+ m_rmm (std::make_unique<region_model_manager> (*this))
+{
+}
+
+symbolic::node_manager::~node_manager () = default;
+
+/* Dump the various managers to LOGGER.
+ If SHOW_OBJS is true, also dump the objects themselves. */
+
+void
+symbolic::node_manager::log_stats (logger *logger, bool show_objs) const
+{
+ LOG_SCOPE (logger);
+
+ m_rmm->log_stats (logger, show_objs);
+}
+
} // namespace ana
#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/symbolic-nodes.h b/gcc/analyzer/symbolic-nodes.h
index 990d7c6cb6a..20e0ccaa877 100644
--- a/gcc/analyzer/symbolic-nodes.h
+++ b/gcc/analyzer/symbolic-nodes.h
@@ -26,6 +26,41 @@ along with GCC; see the file COPYING3. If not see
namespace ana {
namespace symbolic {
+/* A central hub for managing symbolic::node instances
+ - Provides a central authority for handing out IDs for new nodes.
+ - Owns the various managers of symbolic::node subclasses and provides
+ a central place for them to find each other.
+
+ We use pointers to the managers to minimize compile-time dependencies.
+
+ This is effectively a singleton during analysis (but each unit test
+ gets its own instance). */
+
+class node_manager
+{
+public:
+ node_manager ();
+ ~node_manager ();
+
+ node_manager (const node_manager &) = delete;
+
+ unsigned get_num_nodes () const { return m_next_node_id; }
+ unsigned alloc_node_id () { return m_next_node_id++; }
+
+ region_model_manager &
+ get_region_model_manager () const { return *m_rmm; }
+
+ region_model_manager &
+ get_svalue_manager () const { return *m_rmm; }
+
+ void log_stats (logger *logger, bool show_objs) const;
+
+private:
+ unsigned m_next_node_id;
+
+ std::unique_ptr<region_model_manager> m_rmm;
+};
+
/* Abstract base class for the various tree-like purely-functional
data structures we use during symbolic execution.
--
2.56.0