analyzer: add symbol base class, moving region id to there [PR104940]
This patch introduces a "symbol" base class that region and svalue both inherit from, generalizing the ID from the region class so it's also used by svalues. This gives a way of sorting regions and svalues into creation order, which I've found useful in my experiments with adding SMT support (PR analyzer/104940). gcc/ChangeLog: PR analyzer/104940 * Makefile.in (ANALYZER_OBJS): Add analyzer/symbol.o. gcc/analyzer/ChangeLog: PR analyzer/104940 * region-model-manager.cc (region_model_manager::region_model_manager): Update for generalizing region ids to also cover svalues. (region_model_manager::get_or_create_constant_svalue): Likewise. (region_model_manager::get_or_create_unknown_svalue): Likewise. (region_model_manager::create_unique_svalue): Likewise. (region_model_manager::get_or_create_initial_value): Likewise. (region_model_manager::get_or_create_setjmp_svalue): Likewise. (region_model_manager::get_or_create_poisoned_svalue): Likewise. (region_model_manager::get_ptr_svalue): Likewise. (region_model_manager::get_or_create_unaryop): Likewise. (region_model_manager::get_or_create_binop): Likewise. (region_model_manager::get_or_create_sub_svalue): Likewise. (region_model_manager::get_or_create_repeated_svalue): Likewise. (region_model_manager::get_or_create_bits_within): Likewise. (region_model_manager::get_or_create_unmergeable): Likewise. (region_model_manager::get_or_create_widening_svalue): Likewise. (region_model_manager::get_or_create_compound_svalue): Likewise. (region_model_manager::get_or_create_conjured_svalue): Likewise. (region_model_manager::get_or_create_asm_output_svalue): Likewise. (region_model_manager::get_or_create_const_fn_result_svalue): Likewise. (region_model_manager::get_region_for_fndecl): Likewise. (region_model_manager::get_region_for_label): Likewise. (region_model_manager::get_region_for_global): Likewise. (region_model_manager::get_field_region): Likewise. (region_model_manager::get_element_region): Likewise. (region_model_manager::get_offset_region): Likewise. (region_model_manager::get_sized_region): Likewise. (region_model_manager::get_cast_region): Likewise. (region_model_manager::get_frame_region): Likewise. (region_model_manager::get_symbolic_region): Likewise. (region_model_manager::get_region_for_string): Likewise. (region_model_manager::get_bit_range): Likewise. (region_model_manager::get_var_arg_region): Likewise. (region_model_manager::get_region_for_unexpected_tree_code): Likewise. (region_model_manager::get_or_create_region_for_heap_alloc): Likewise. (region_model_manager::create_region_for_alloca): Likewise. (region_model_manager::log_stats): Likewise. * region-model-manager.h (region_model_manager::get_num_regions): Replace with... (region_model_manager::get_num_symbols): ...this. (region_model_manager::alloc_region_id): Replace with... (region_model_manager::alloc_symbol_id): ...this. (region_model_manager::m_next_region_id): Replace with... (region_model_manager::m_next_symbol_id): ...this. * region-model.cc (selftest::test_get_representative_tree): Update for generalizing region ids to also cover svalues. (selftest::test_binop_svalue_folding): Likewise. (selftest::test_state_merging): Likewise. * region.cc (region::cmp_ids): Delete, in favor of symbol::cmp_ids. (region::region): Update for introduction of symbol base class. (frame_region::get_region_for_local): Likewise. (root_region::root_region): Likewise. (symbolic_region::symbolic_region): Likewise. * region.h: Replace include of "analyzer/complexity.h" with "analyzer/symbol.h". (class region): Make a subclass of symbol. (region::get_id): Delete in favor of symbol::get_id. (region::cmp_ids): Delete in favor of symbol::cmp_ids. (region::get_complexity): Delete in favor of symbol::get_complexity. (region::region): Use symbol::id_t for "id" param. (region::m_complexity): Move field to symbol base class. (region::m_id): Likewise. (space_region::space_region): Use symbol::id_t for "id" param. (frame_region::frame_region): Likewise. (globals_region::globals_region): Likewise. (code_region::code_region): Likewise. (function_region::function_region): Likewise. (label_region::label_region): Likewise. (stack_region::stack_region): Likewise. (heap_region::heap_region): Likewise. (thread_local_region::thread_local_region): Likewise. (root_region::root_region): Likewise. (symbolic_region::symbolic_region): Likewise. (decl_region::decl_region): Likewise. (field_region::field_region): Likewise. (element_region::element_region): Likewise. (offset_region::offset_region): Likewise. (sized_region::sized_region): Likewise. (cast_region::cast_region): Likewise. (heap_allocated_region::heap_allocated_region): Likewise. (alloca_region::alloca_region): Likewise. (string_region::string_region): Likewise. (bit_range_region::bit_range_region): Likewise. (var_arg_region::var_arg_region): Likewise. (errno_region::errno_region): Likewise. (unknown_region::unknown_region): Likewise. * svalue.cc (sub_svalue::sub_svalue): Add symbol::id_t param. (repeated_svalue::repeated_svalue): Likewise. (bits_within_svalue::bits_within_svalue): Likewise. (compound_svalue::compound_svalue): Likewise. * svalue.h: Replace include of "analyzer/complexity.h" with "analyzer/symbol.h". (class svalue): Make a subclass of symbol. (svalue::get_complexity): Delete in favor of symbol::get_complexity. (svalue::svalue): Add symbol::id_t param. Update for new base class. (svalue::m_complexity): Delete in favor of symbol::m_complexity. (region_svalue::region_svalue): Add symbol::id_t param (constant_svalue::constant_svalue): Likewise. (unknown_svalue::unknown_svalue): Likewise. (poisoned_svalue::poisoned_svalue): Likewise. (setjmp_svalue::setjmp_svalue): Likewise. (initial_svalue::initial_svalue): Likewise. (unaryop_svalue::unaryop_svalue): Likewise. (binop_svalue::binop_svalue): Likewise. (sub_svalue::sub_svalue): Likewise. (repeated_svalue::repeated_svalue): Likewise. (bits_within_svalue::bits_within_svalue): Likewise. (unmergeable_svalue::unmergeable_svalue): Likewise. (placeholder_svalue::placeholder_svalue): Likewise. (widening_svalue::widening_svalue): Likewise. (compound_svalue::compound_svalue): Likewise. (conjured_svalue::conjured_svalue): Likewise. (asm_output_svalue::asm_output_svalue): Likewise. (const_fn_result_svalue::const_fn_result_svalue): Likewise. * symbol.cc: New file. * symbol.h: New file. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
25072a477a
commit
9d804f9b27
10 changed files with 263 additions and 150 deletions
|
@ -1327,6 +1327,7 @@ ANALYZER_OBJS = \
|
|||
analyzer/store.o \
|
||||
analyzer/supergraph.o \
|
||||
analyzer/svalue.o \
|
||||
analyzer/symbol.o \
|
||||
analyzer/trimmed-graph.o \
|
||||
analyzer/varargs.o
|
||||
|
||||
|
|
|
@ -62,20 +62,20 @@ namespace ana {
|
|||
|
||||
region_model_manager::region_model_manager (logger *logger)
|
||||
: m_logger (logger),
|
||||
m_next_symbol_id (0),
|
||||
m_empty_call_string (),
|
||||
m_next_region_id (0),
|
||||
m_root_region (alloc_region_id ()),
|
||||
m_stack_region (alloc_region_id (), &m_root_region),
|
||||
m_heap_region (alloc_region_id (), &m_root_region),
|
||||
m_root_region (alloc_symbol_id ()),
|
||||
m_stack_region (alloc_symbol_id (), &m_root_region),
|
||||
m_heap_region (alloc_symbol_id (), &m_root_region),
|
||||
m_unknown_NULL (NULL),
|
||||
m_checking_feasibility (false),
|
||||
m_max_complexity (0, 0),
|
||||
m_code_region (alloc_region_id (), &m_root_region),
|
||||
m_code_region (alloc_symbol_id (), &m_root_region),
|
||||
m_fndecls_map (), m_labels_map (),
|
||||
m_globals_region (alloc_region_id (), &m_root_region),
|
||||
m_globals_region (alloc_symbol_id (), &m_root_region),
|
||||
m_globals_map (),
|
||||
m_thread_local_region (alloc_region_id (), &m_root_region),
|
||||
m_errno_region (alloc_region_id (), &m_thread_local_region),
|
||||
m_thread_local_region (alloc_symbol_id (), &m_root_region),
|
||||
m_errno_region (alloc_symbol_id (), &m_thread_local_region),
|
||||
m_store_mgr (this),
|
||||
m_range_mgr (new bounded_ranges_manager ()),
|
||||
m_known_fn_mgr (logger)
|
||||
|
@ -220,7 +220,8 @@ region_model_manager::get_or_create_constant_svalue (tree cst_expr)
|
|||
constant_svalue **slot = m_constants_map.get (cst_expr);
|
||||
if (slot)
|
||||
return *slot;
|
||||
constant_svalue *cst_sval = new constant_svalue (cst_expr);
|
||||
constant_svalue *cst_sval
|
||||
= new constant_svalue (alloc_symbol_id (), cst_expr);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (cst_sval);
|
||||
m_constants_map.put (cst_expr, cst_sval);
|
||||
return cst_sval;
|
||||
|
@ -268,14 +269,14 @@ region_model_manager::get_or_create_unknown_svalue (tree type)
|
|||
if (type == NULL_TREE)
|
||||
{
|
||||
if (!m_unknown_NULL)
|
||||
m_unknown_NULL = new unknown_svalue (type);
|
||||
m_unknown_NULL = new unknown_svalue (alloc_symbol_id (), type);
|
||||
return m_unknown_NULL;
|
||||
}
|
||||
|
||||
unknown_svalue **slot = m_unknowns_map.get (type);
|
||||
if (slot)
|
||||
return *slot;
|
||||
unknown_svalue *sval = new unknown_svalue (type);
|
||||
unknown_svalue *sval = new unknown_svalue (alloc_symbol_id (), type);
|
||||
m_unknowns_map.put (type, sval);
|
||||
return sval;
|
||||
}
|
||||
|
@ -285,7 +286,7 @@ region_model_manager::get_or_create_unknown_svalue (tree type)
|
|||
const svalue *
|
||||
region_model_manager::create_unique_svalue (tree type)
|
||||
{
|
||||
svalue *sval = new placeholder_svalue (type, "unique");
|
||||
svalue *sval = new placeholder_svalue (alloc_symbol_id (), type, "unique");
|
||||
m_managed_dynamic_svalues.safe_push (sval);
|
||||
return sval;
|
||||
}
|
||||
|
@ -315,7 +316,8 @@ region_model_manager::get_or_create_initial_value (const region *reg,
|
|||
|
||||
if (initial_svalue **slot = m_initial_values_map.get (reg))
|
||||
return *slot;
|
||||
initial_svalue *initial_sval = new initial_svalue (reg->get_type (), reg);
|
||||
initial_svalue *initial_sval
|
||||
= new initial_svalue (alloc_symbol_id (), reg->get_type (), reg);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (initial_sval);
|
||||
m_initial_values_map.put (reg, initial_sval);
|
||||
return initial_sval;
|
||||
|
@ -331,7 +333,7 @@ region_model_manager::get_or_create_setjmp_svalue (const setjmp_record &r,
|
|||
setjmp_svalue::key_t key (r, type);
|
||||
if (setjmp_svalue **slot = m_setjmp_values_map.get (key))
|
||||
return *slot;
|
||||
setjmp_svalue *setjmp_sval = new setjmp_svalue (r, type);
|
||||
setjmp_svalue *setjmp_sval = new setjmp_svalue (r, alloc_symbol_id (), type);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (setjmp_sval);
|
||||
m_setjmp_values_map.put (key, setjmp_sval);
|
||||
return setjmp_sval;
|
||||
|
@ -347,7 +349,8 @@ region_model_manager::get_or_create_poisoned_svalue (enum poison_kind kind,
|
|||
poisoned_svalue::key_t key (kind, type);
|
||||
if (poisoned_svalue **slot = m_poisoned_values_map.get (key))
|
||||
return *slot;
|
||||
poisoned_svalue *poisoned_sval = new poisoned_svalue (kind, type);
|
||||
poisoned_svalue *poisoned_sval
|
||||
= new poisoned_svalue (kind, alloc_symbol_id (), type);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (poisoned_sval);
|
||||
m_poisoned_values_map.put (key, poisoned_sval);
|
||||
return poisoned_sval;
|
||||
|
@ -368,7 +371,8 @@ region_model_manager::get_ptr_svalue (tree ptr_type, const region *pointee)
|
|||
region_svalue::key_t key (ptr_type, pointee);
|
||||
if (region_svalue **slot = m_pointer_values_map.get (key))
|
||||
return *slot;
|
||||
region_svalue *sval = new region_svalue (ptr_type, pointee);
|
||||
region_svalue *sval
|
||||
= new region_svalue (alloc_symbol_id (), ptr_type, pointee);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (sval);
|
||||
m_pointer_values_map.put (key, sval);
|
||||
return sval;
|
||||
|
@ -491,7 +495,8 @@ region_model_manager::get_or_create_unaryop (tree type, enum tree_code op,
|
|||
unaryop_svalue::key_t key (type, op, arg);
|
||||
if (unaryop_svalue **slot = m_unaryop_values_map.get (key))
|
||||
return *slot;
|
||||
unaryop_svalue *unaryop_sval = new unaryop_svalue (type, op, arg);
|
||||
unaryop_svalue *unaryop_sval
|
||||
= new unaryop_svalue (alloc_symbol_id (), type, op, arg);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (unaryop_sval);
|
||||
m_unaryop_values_map.put (key, unaryop_sval);
|
||||
return unaryop_sval;
|
||||
|
@ -797,7 +802,8 @@ region_model_manager::get_or_create_binop (tree type, enum tree_code op,
|
|||
binop_svalue::key_t key (type, op, arg0, arg1);
|
||||
if (binop_svalue **slot = m_binop_values_map.get (key))
|
||||
return *slot;
|
||||
binop_svalue *binop_sval = new binop_svalue (type, op, arg0, arg1);
|
||||
binop_svalue *binop_sval
|
||||
= new binop_svalue (alloc_symbol_id (), type, op, arg0, arg1);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (binop_sval);
|
||||
m_binop_values_map.put (key, binop_sval);
|
||||
return binop_sval;
|
||||
|
@ -903,7 +909,7 @@ region_model_manager::get_or_create_sub_svalue (tree type,
|
|||
if (sub_svalue **slot = m_sub_values_map.get (key))
|
||||
return *slot;
|
||||
sub_svalue *sub_sval
|
||||
= new sub_svalue (type, parent_svalue, subregion);
|
||||
= new sub_svalue (alloc_symbol_id (), type, parent_svalue, subregion);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (sub_sval);
|
||||
m_sub_values_map.put (key, sub_sval);
|
||||
return sub_sval;
|
||||
|
@ -964,7 +970,7 @@ region_model_manager::get_or_create_repeated_svalue (tree type,
|
|||
if (repeated_svalue **slot = m_repeated_values_map.get (key))
|
||||
return *slot;
|
||||
repeated_svalue *repeated_sval
|
||||
= new repeated_svalue (type, outer_size, inner_svalue);
|
||||
= new repeated_svalue (alloc_symbol_id (), type, outer_size, inner_svalue);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (repeated_sval);
|
||||
m_repeated_values_map.put (key, repeated_sval);
|
||||
return repeated_sval;
|
||||
|
@ -1157,7 +1163,7 @@ region_model_manager::get_or_create_bits_within (tree type,
|
|||
if (bits_within_svalue **slot = m_bits_within_values_map.get (key))
|
||||
return *slot;
|
||||
bits_within_svalue *bits_within_sval
|
||||
= new bits_within_svalue (type, bits, inner_svalue);
|
||||
= new bits_within_svalue (alloc_symbol_id (), type, bits, inner_svalue);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (bits_within_sval);
|
||||
m_bits_within_values_map.put (key, bits_within_sval);
|
||||
return bits_within_sval;
|
||||
|
@ -1174,7 +1180,8 @@ region_model_manager::get_or_create_unmergeable (const svalue *arg)
|
|||
|
||||
if (unmergeable_svalue **slot = m_unmergeable_values_map.get (arg))
|
||||
return *slot;
|
||||
unmergeable_svalue *unmergeable_sval = new unmergeable_svalue (arg);
|
||||
unmergeable_svalue *unmergeable_sval
|
||||
= new unmergeable_svalue (alloc_symbol_id (), arg);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (unmergeable_sval);
|
||||
m_unmergeable_values_map.put (arg, unmergeable_sval);
|
||||
return unmergeable_sval;
|
||||
|
@ -1196,7 +1203,8 @@ get_or_create_widening_svalue (tree type,
|
|||
if (widening_svalue **slot = m_widening_values_map.get (key))
|
||||
return *slot;
|
||||
widening_svalue *widening_sval
|
||||
= new widening_svalue (type, point, base_sval, iter_sval);
|
||||
= new widening_svalue (alloc_symbol_id (), type, point, base_sval,
|
||||
iter_sval);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (widening_sval);
|
||||
m_widening_values_map.put (key, widening_sval);
|
||||
return widening_sval;
|
||||
|
@ -1213,7 +1221,7 @@ region_model_manager::get_or_create_compound_svalue (tree type,
|
|||
if (compound_svalue **slot = m_compound_values_map.get (tmp_key))
|
||||
return *slot;
|
||||
compound_svalue *compound_sval
|
||||
= new compound_svalue (type, map);
|
||||
= new compound_svalue (alloc_symbol_id (), type, map);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (compound_sval);
|
||||
/* Use make_key rather than reusing the key, so that we use a
|
||||
ptr to compound_sval's binding_map, rather than the MAP param. */
|
||||
|
@ -1254,7 +1262,7 @@ region_model_manager::get_or_create_conjured_svalue (tree type,
|
|||
return sval;
|
||||
}
|
||||
conjured_svalue *conjured_sval
|
||||
= new conjured_svalue (type, stmt, id_reg);
|
||||
= new conjured_svalue (alloc_symbol_id (), type, stmt, id_reg);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (conjured_sval);
|
||||
m_conjured_values_map.put (key, conjured_sval);
|
||||
return conjured_sval;
|
||||
|
@ -1299,7 +1307,8 @@ get_or_create_asm_output_svalue (tree type,
|
|||
if (asm_output_svalue **slot = m_asm_output_values_map.get (key))
|
||||
return *slot;
|
||||
asm_output_svalue *asm_output_sval
|
||||
= new asm_output_svalue (type, asm_string, output_idx, noutputs, inputs);
|
||||
= new asm_output_svalue (alloc_symbol_id (), type, asm_string, output_idx,
|
||||
noutputs, inputs);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (asm_output_sval);
|
||||
m_asm_output_values_map.put (key, asm_output_sval);
|
||||
return asm_output_sval;
|
||||
|
@ -1327,7 +1336,8 @@ get_or_create_asm_output_svalue (tree type,
|
|||
if (asm_output_svalue **slot = m_asm_output_values_map.get (key))
|
||||
return *slot;
|
||||
asm_output_svalue *asm_output_sval
|
||||
= new asm_output_svalue (type, asm_string, output_idx, num_outputs, inputs);
|
||||
= new asm_output_svalue (alloc_symbol_id (), type, asm_string, output_idx,
|
||||
num_outputs, inputs);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (asm_output_sval);
|
||||
m_asm_output_values_map.put (key, asm_output_sval);
|
||||
return asm_output_sval;
|
||||
|
@ -1352,7 +1362,7 @@ get_or_create_const_fn_result_svalue (tree type,
|
|||
if (const_fn_result_svalue **slot = m_const_fn_result_values_map.get (key))
|
||||
return *slot;
|
||||
const_fn_result_svalue *const_fn_result_sval
|
||||
= new const_fn_result_svalue (type, fndecl, inputs);
|
||||
= new const_fn_result_svalue (alloc_symbol_id (), type, fndecl, inputs);
|
||||
RETURN_UNKNOWN_IF_TOO_COMPLEX (const_fn_result_sval);
|
||||
m_const_fn_result_values_map.put (key, const_fn_result_sval);
|
||||
return const_fn_result_sval;
|
||||
|
@ -1399,7 +1409,7 @@ region_model_manager::get_region_for_fndecl (tree fndecl)
|
|||
if (slot)
|
||||
return *slot;
|
||||
function_region *reg
|
||||
= new function_region (alloc_region_id (), &m_code_region, fndecl);
|
||||
= new function_region (alloc_symbol_id (), &m_code_region, fndecl);
|
||||
m_fndecls_map.put (fndecl, reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1420,7 +1430,7 @@ region_model_manager::get_region_for_label (tree label)
|
|||
|
||||
const function_region *func_reg = get_region_for_fndecl (fndecl);
|
||||
label_region *reg
|
||||
= new label_region (alloc_region_id (), func_reg, label);
|
||||
= new label_region (alloc_symbol_id (), func_reg, label);
|
||||
m_labels_map.put (label, reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1436,7 +1446,7 @@ region_model_manager::get_region_for_global (tree expr)
|
|||
if (slot)
|
||||
return *slot;
|
||||
decl_region *reg
|
||||
= new decl_region (alloc_region_id (), &m_globals_region, expr);
|
||||
= new decl_region (alloc_symbol_id (), &m_globals_region, expr);
|
||||
m_globals_map.put (expr, reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1471,7 +1481,7 @@ region_model_manager::get_field_region (const region *parent, tree field)
|
|||
return reg;
|
||||
|
||||
field_region *field_reg
|
||||
= new field_region (alloc_region_id (), parent, field);
|
||||
= new field_region (alloc_symbol_id (), parent, field);
|
||||
m_field_regions.put (key, field_reg);
|
||||
return field_reg;
|
||||
}
|
||||
|
@ -1493,7 +1503,7 @@ region_model_manager::get_element_region (const region *parent,
|
|||
return reg;
|
||||
|
||||
element_region *element_reg
|
||||
= new element_region (alloc_region_id (), parent, element_type, index);
|
||||
= new element_region (alloc_symbol_id (), parent, element_type, index);
|
||||
m_element_regions.put (key, element_reg);
|
||||
return element_reg;
|
||||
}
|
||||
|
@ -1533,7 +1543,7 @@ region_model_manager::get_offset_region (const region *parent,
|
|||
return reg;
|
||||
|
||||
offset_region *offset_reg
|
||||
= new offset_region (alloc_region_id (), parent, type, byte_offset);
|
||||
= new offset_region (alloc_symbol_id (), parent, type, byte_offset);
|
||||
m_offset_regions.put (key, offset_reg);
|
||||
return offset_reg;
|
||||
}
|
||||
|
@ -1568,7 +1578,7 @@ region_model_manager::get_sized_region (const region *parent,
|
|||
return reg;
|
||||
|
||||
sized_region *sized_reg
|
||||
= new sized_region (alloc_region_id (), parent, type, byte_size_sval);
|
||||
= new sized_region (alloc_symbol_id (), parent, type, byte_size_sval);
|
||||
m_sized_regions.put (key, sized_reg);
|
||||
return sized_reg;
|
||||
}
|
||||
|
@ -1592,7 +1602,7 @@ region_model_manager::get_cast_region (const region *original_region,
|
|||
return reg;
|
||||
|
||||
cast_region *cast_reg
|
||||
= new cast_region (alloc_region_id (), original_region, type);
|
||||
= new cast_region (alloc_symbol_id (), original_region, type);
|
||||
m_cast_regions.put (key, cast_reg);
|
||||
return cast_reg;
|
||||
}
|
||||
|
@ -1611,7 +1621,7 @@ region_model_manager::get_frame_region (const frame_region *calling_frame,
|
|||
return reg;
|
||||
|
||||
frame_region *frame_reg
|
||||
= new frame_region (alloc_region_id (), &m_stack_region, calling_frame,
|
||||
= new frame_region (alloc_symbol_id (), &m_stack_region, calling_frame,
|
||||
fun, index);
|
||||
m_frame_regions.put (key, frame_reg);
|
||||
return frame_reg;
|
||||
|
@ -1628,7 +1638,7 @@ region_model_manager::get_symbolic_region (const svalue *sval)
|
|||
return reg;
|
||||
|
||||
symbolic_region *symbolic_reg
|
||||
= new symbolic_region (alloc_region_id (), &m_root_region, sval);
|
||||
= new symbolic_region (alloc_symbol_id (), &m_root_region, sval);
|
||||
m_symbolic_regions.put (key, symbolic_reg);
|
||||
return symbolic_reg;
|
||||
}
|
||||
|
@ -1645,7 +1655,7 @@ region_model_manager::get_region_for_string (tree string_cst)
|
|||
if (slot)
|
||||
return *slot;
|
||||
string_region *reg
|
||||
= new string_region (alloc_region_id (), &m_root_region, string_cst);
|
||||
= new string_region (alloc_symbol_id (), &m_root_region, string_cst);
|
||||
m_string_map.put (string_cst, reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1667,7 +1677,7 @@ region_model_manager::get_bit_range (const region *parent, tree type,
|
|||
return reg;
|
||||
|
||||
bit_range_region *bit_range_reg
|
||||
= new bit_range_region (alloc_region_id (), parent, type, bits);
|
||||
= new bit_range_region (alloc_symbol_id (), parent, type, bits);
|
||||
m_bit_range_regions.put (key, bit_range_reg);
|
||||
return bit_range_reg;
|
||||
}
|
||||
|
@ -1686,7 +1696,7 @@ region_model_manager::get_var_arg_region (const frame_region *parent_frame,
|
|||
return reg;
|
||||
|
||||
var_arg_region *var_arg_reg
|
||||
= new var_arg_region (alloc_region_id (), parent_frame, idx);
|
||||
= new var_arg_region (alloc_symbol_id (), parent_frame, idx);
|
||||
m_var_arg_regions.put (key, var_arg_reg);
|
||||
return var_arg_reg;
|
||||
}
|
||||
|
@ -1706,7 +1716,7 @@ get_region_for_unexpected_tree_code (region_model_context *ctxt,
|
|||
{
|
||||
tree type = TYPE_P (t) ? t : TREE_TYPE (t);
|
||||
region *new_reg
|
||||
= new unknown_region (alloc_region_id (), &m_root_region, type);
|
||||
= new unknown_region (alloc_symbol_id (), &m_root_region, type);
|
||||
if (ctxt)
|
||||
ctxt->on_unexpected_tree_code (t, loc);
|
||||
return new_reg;
|
||||
|
@ -1729,7 +1739,7 @@ get_or_create_region_for_heap_alloc (const bitmap &base_regs_in_use)
|
|||
|
||||
/* All existing ones (if any) are in use; create a new one. */
|
||||
region *reg
|
||||
= new heap_allocated_region (alloc_region_id (), &m_heap_region);
|
||||
= new heap_allocated_region (alloc_symbol_id (), &m_heap_region);
|
||||
m_managed_dynamic_regions.safe_push (reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1740,7 +1750,7 @@ const region *
|
|||
region_model_manager::create_region_for_alloca (const frame_region *frame)
|
||||
{
|
||||
gcc_assert (frame);
|
||||
region *reg = new alloca_region (alloc_region_id (), frame);
|
||||
region *reg = new alloca_region (alloc_symbol_id (), frame);
|
||||
m_managed_dynamic_regions.safe_push (reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1832,6 +1842,7 @@ 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 symbol id: %i", m_next_symbol_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);
|
||||
|
@ -1863,7 +1874,6 @@ region_model_manager::log_stats (logger *logger, bool show_objs) const
|
|||
m_max_complexity.m_max_depth);
|
||||
|
||||
logger->log ("region consolidation");
|
||||
logger->log (" next region id: %i", m_next_region_id);
|
||||
log_uniq_map (logger, show_objs, "function_region", m_fndecls_map);
|
||||
log_uniq_map (logger, show_objs, "label_region", m_labels_map);
|
||||
log_uniq_map (logger, show_objs, "decl_region for globals", m_globals_map);
|
||||
|
|
|
@ -34,6 +34,9 @@ public:
|
|||
region_model_manager (logger *logger = NULL);
|
||||
~region_model_manager ();
|
||||
|
||||
unsigned get_num_symbols () const { return m_next_symbol_id; }
|
||||
unsigned alloc_symbol_id () { return m_next_symbol_id++; }
|
||||
|
||||
/* call_string consolidation. */
|
||||
const call_string &get_empty_call_string () const
|
||||
{
|
||||
|
@ -102,7 +105,6 @@ public:
|
|||
const svalue *create_unique_svalue (tree type);
|
||||
|
||||
/* region consolidation. */
|
||||
unsigned get_num_regions () const { return m_next_region_id; }
|
||||
const stack_region * get_stack_region () const { return &m_stack_region; }
|
||||
const heap_region *get_heap_region () const { return &m_heap_region; }
|
||||
const code_region *get_code_region () const { return &m_code_region; }
|
||||
|
@ -142,8 +144,6 @@ public:
|
|||
tree t,
|
||||
const dump_location_t &loc);
|
||||
|
||||
unsigned alloc_region_id () { return m_next_region_id++; }
|
||||
|
||||
store_manager *get_store_manager () { return &m_store_mgr; }
|
||||
bounded_ranges_manager *get_range_manager () const { return m_range_mgr; }
|
||||
|
||||
|
@ -193,9 +193,10 @@ private:
|
|||
|
||||
logger *m_logger;
|
||||
|
||||
unsigned m_next_symbol_id;
|
||||
|
||||
const call_string m_empty_call_string;
|
||||
|
||||
unsigned m_next_region_id;
|
||||
root_region m_root_region;
|
||||
stack_region m_stack_region;
|
||||
heap_region m_heap_region;
|
||||
|
|
|
@ -6161,7 +6161,8 @@ 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 (char_type_node, "test value");
|
||||
placeholder_svalue test_sval (mgr.alloc_symbol_id (),
|
||||
char_type_node, "test value");
|
||||
|
||||
/* Value of a[3]. */
|
||||
{
|
||||
|
@ -6206,7 +6207,8 @@ test_get_representative_tree ()
|
|||
{
|
||||
region_model m (&mgr);
|
||||
const region *c_x_reg = m.get_lvalue (c_x, &ctxt);
|
||||
placeholder_svalue test_sval_x (integer_type_node, "test x val");
|
||||
placeholder_svalue test_sval_x (mgr.alloc_symbol_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);
|
||||
ASSERT_DUMP_TREE_EQ (rep, "c.x");
|
||||
|
@ -6216,7 +6218,8 @@ test_get_representative_tree ()
|
|||
{
|
||||
region_model m (&mgr);
|
||||
const region *c_y_reg = m.get_lvalue (c_y, &ctxt);
|
||||
placeholder_svalue test_sval_y (integer_type_node, "test y val");
|
||||
placeholder_svalue test_sval_y (mgr.alloc_symbol_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);
|
||||
ASSERT_DUMP_TREE_EQ (rep, "c.y");
|
||||
|
@ -6460,7 +6463,8 @@ test_binop_svalue_folding ()
|
|||
const svalue *sval_false = mgr.get_or_create_int_cst (boolean_type_node, 0);
|
||||
const svalue *sval_unknown
|
||||
= mgr.get_or_create_unknown_svalue (boolean_type_node);
|
||||
const placeholder_svalue sval_placeholder (boolean_type_node, "v");
|
||||
const placeholder_svalue sval_placeholder (mgr.alloc_symbol_id (),
|
||||
boolean_type_node, "v");
|
||||
for (auto op : {BIT_IOR_EXPR, TRUTH_OR_EXPR})
|
||||
{
|
||||
ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
|
||||
|
@ -7072,7 +7076,8 @@ test_state_merging ()
|
|||
ASSERT_EQ (model0.get_stack_depth (), 1);
|
||||
model1.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, &ctxt);
|
||||
|
||||
placeholder_svalue test_sval (integer_type_node, "test sval");
|
||||
placeholder_svalue test_sval (mgr.alloc_symbol_id (),
|
||||
integer_type_node, "test sval");
|
||||
model0.set_value (model0.get_lvalue (a, &ctxt), &test_sval, &ctxt);
|
||||
model1.set_value (model1.get_lvalue (a, &ctxt), &test_sval, &ctxt);
|
||||
ASSERT_EQ (model0, model1);
|
||||
|
@ -7091,7 +7096,8 @@ test_state_merging ()
|
|||
region_model model0 (&mgr);
|
||||
region_model model1 (&mgr);
|
||||
|
||||
placeholder_svalue test_sval (integer_type_node, "test sval");
|
||||
placeholder_svalue test_sval (mgr.alloc_symbol_id (),
|
||||
integer_type_node, "test sval");
|
||||
model0.set_value (model0.get_lvalue (x, &ctxt), &test_sval, &ctxt);
|
||||
model1.set_value (model1.get_lvalue (x, &ctxt), &test_sval, &ctxt);
|
||||
ASSERT_EQ (model0, model1);
|
||||
|
@ -7231,7 +7237,8 @@ test_state_merging ()
|
|||
{
|
||||
test_region_model_context ctxt;
|
||||
region_model model0 (&mgr);
|
||||
placeholder_svalue placeholder_sval (integer_type_node, "test");
|
||||
placeholder_svalue placeholder_sval (mgr.alloc_symbol_id (),
|
||||
integer_type_node, "test");
|
||||
model0.set_value (model0.get_lvalue (x, &ctxt),
|
||||
&placeholder_sval, &ctxt);
|
||||
model0.set_value (model0.get_lvalue (y, &ctxt), &placeholder_sval, &ctxt);
|
||||
|
|
|
@ -398,14 +398,6 @@ region::~region ()
|
|||
delete m_cached_offset;
|
||||
}
|
||||
|
||||
/* Compare REG1 and REG2 by id. */
|
||||
|
||||
int
|
||||
region::cmp_ids (const region *reg1, const region *reg2)
|
||||
{
|
||||
return (long)reg1->get_id () - (long)reg2->get_id ();
|
||||
}
|
||||
|
||||
/* Determine the base region for this region: when considering bindings
|
||||
for this region, the base region is the ancestor which identifies
|
||||
which cluster they should be partitioned into.
|
||||
|
@ -1099,8 +1091,9 @@ region::is_named_decl_p (const char *decl_name) const
|
|||
|
||||
/* region's ctor. */
|
||||
|
||||
region::region (complexity c, unsigned id, const region *parent, tree type)
|
||||
: m_complexity (c), m_id (id), m_parent (parent), m_type (type),
|
||||
region::region (complexity c, symbol::id_t id, const region *parent, tree type)
|
||||
: symbol (c, id),
|
||||
m_parent (parent), m_type (type),
|
||||
m_cached_offset (NULL), m_cached_init_sval_at_main (NULL)
|
||||
{
|
||||
gcc_assert (type == NULL_TREE || TYPE_P (type));
|
||||
|
@ -1347,7 +1340,7 @@ frame_region::get_region_for_local (region_model_manager *mgr,
|
|||
if (decl_region **slot = mutable_locals.get (expr))
|
||||
return *slot;
|
||||
decl_region *reg
|
||||
= new decl_region (mgr->alloc_region_id (), this, expr);
|
||||
= new decl_region (mgr->alloc_symbol_id (), this, expr);
|
||||
mutable_locals.put (expr, reg);
|
||||
return reg;
|
||||
}
|
||||
|
@ -1446,7 +1439,7 @@ heap_region::dump_to_pp (pretty_printer *pp, bool simple) const
|
|||
|
||||
/* root_region's ctor. */
|
||||
|
||||
root_region::root_region (unsigned id)
|
||||
root_region::root_region (symbol::id_t id)
|
||||
: region (complexity (1, 1), id, NULL, NULL_TREE)
|
||||
{
|
||||
}
|
||||
|
@ -1477,7 +1470,7 @@ thread_local_region::dump_to_pp (pretty_printer *pp, bool simple) const
|
|||
|
||||
/* symbolic_region's ctor. */
|
||||
|
||||
symbolic_region::symbolic_region (unsigned id, region *parent,
|
||||
symbolic_region::symbolic_region (symbol::id_t id, region *parent,
|
||||
const svalue *sval_ptr)
|
||||
: region (complexity::from_pair (parent, sval_ptr), id, parent,
|
||||
(sval_ptr->get_type ()
|
||||
|
|
|
@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#ifndef GCC_ANALYZER_REGION_H
|
||||
#define GCC_ANALYZER_REGION_H
|
||||
|
||||
#include "analyzer/complexity.h"
|
||||
#include "analyzer/symbol.h"
|
||||
|
||||
namespace ana {
|
||||
|
||||
|
@ -118,14 +118,11 @@ enum region_kind
|
|||
within the frames and the "globals" region. Regions for structs
|
||||
can have subregions for fields. */
|
||||
|
||||
class region
|
||||
class region : public symbol
|
||||
{
|
||||
public:
|
||||
virtual ~region ();
|
||||
|
||||
unsigned get_id () const { return m_id; }
|
||||
static int cmp_ids (const region *reg1, const region *reg2);
|
||||
|
||||
virtual enum region_kind get_kind () const = 0;
|
||||
virtual const frame_region *
|
||||
dyn_cast_frame_region () const { return NULL; }
|
||||
|
@ -231,21 +228,17 @@ public:
|
|||
bloating the store object with redundant binding clusters). */
|
||||
virtual bool tracked_p () const { return true; }
|
||||
|
||||
const complexity &get_complexity () const { return m_complexity; }
|
||||
|
||||
bool is_named_decl_p (const char *decl_name) const;
|
||||
|
||||
bool empty_p () const;
|
||||
|
||||
protected:
|
||||
region (complexity c, unsigned id, const region *parent, tree type);
|
||||
region (complexity c, symbol::id_t id, const region *parent, tree type);
|
||||
|
||||
private:
|
||||
region_offset calc_offset (region_model_manager *mgr) const;
|
||||
const svalue *calc_initial_value_at_main (region_model_manager *mgr) const;
|
||||
|
||||
complexity m_complexity;
|
||||
unsigned m_id; // purely for deterministic sorting at this stage, for dumps
|
||||
const region *m_parent;
|
||||
tree m_type;
|
||||
|
||||
|
@ -274,7 +267,7 @@ namespace ana {
|
|||
class space_region : public region
|
||||
{
|
||||
protected:
|
||||
space_region (unsigned id, const region *parent)
|
||||
space_region (symbol::id_t id, const region *parent)
|
||||
: region (complexity (parent), id, parent, NULL_TREE)
|
||||
{}
|
||||
};
|
||||
|
@ -329,7 +322,7 @@ public:
|
|||
function *m_fun;
|
||||
};
|
||||
|
||||
frame_region (unsigned id, const region *parent,
|
||||
frame_region (symbol::id_t id, const region *parent,
|
||||
const frame_region *calling_frame,
|
||||
function *fun, int index)
|
||||
: space_region (id, parent), m_calling_frame (calling_frame),
|
||||
|
@ -398,7 +391,7 @@ namespace ana {
|
|||
class globals_region : public space_region
|
||||
{
|
||||
public:
|
||||
globals_region (unsigned id, const region *parent)
|
||||
globals_region (symbol::id_t id, const region *parent)
|
||||
: space_region (id, parent)
|
||||
{}
|
||||
|
||||
|
@ -425,7 +418,7 @@ namespace ana {
|
|||
class code_region : public space_region
|
||||
{
|
||||
public:
|
||||
code_region (unsigned id, const region *parent)
|
||||
code_region (symbol::id_t id, const region *parent)
|
||||
: space_region (id, parent)
|
||||
{}
|
||||
|
||||
|
@ -452,7 +445,7 @@ namespace ana {
|
|||
class function_region : public region
|
||||
{
|
||||
public:
|
||||
function_region (unsigned id, const code_region *parent, tree fndecl)
|
||||
function_region (symbol::id_t id, const code_region *parent, tree fndecl)
|
||||
: region (complexity (parent), id, parent, TREE_TYPE (fndecl)),
|
||||
m_fndecl (fndecl)
|
||||
{
|
||||
|
@ -489,7 +482,7 @@ namespace ana {
|
|||
class label_region : public region
|
||||
{
|
||||
public:
|
||||
label_region (unsigned id, const function_region *parent, tree label)
|
||||
label_region (symbol::id_t id, const function_region *parent, tree label)
|
||||
: region (complexity (parent), id, parent, NULL_TREE), m_label (label)
|
||||
{
|
||||
gcc_assert (TREE_CODE (label) == LABEL_DECL);
|
||||
|
@ -523,7 +516,7 @@ namespace ana {
|
|||
class stack_region : public space_region
|
||||
{
|
||||
public:
|
||||
stack_region (unsigned id, region *parent)
|
||||
stack_region (symbol::id_t id, region *parent)
|
||||
: space_region (id, parent)
|
||||
{}
|
||||
|
||||
|
@ -550,7 +543,7 @@ namespace ana {
|
|||
class heap_region : public space_region
|
||||
{
|
||||
public:
|
||||
heap_region (unsigned id, region *parent)
|
||||
heap_region (symbol::id_t id, region *parent)
|
||||
: space_region (id, parent)
|
||||
{}
|
||||
|
||||
|
@ -576,7 +569,7 @@ namespace ana {
|
|||
class thread_local_region : public space_region
|
||||
{
|
||||
public:
|
||||
thread_local_region (unsigned id, region *parent)
|
||||
thread_local_region (symbol::id_t id, region *parent)
|
||||
: space_region (id, parent)
|
||||
{}
|
||||
|
||||
|
@ -603,7 +596,7 @@ namespace ana {
|
|||
class root_region : public region
|
||||
{
|
||||
public:
|
||||
root_region (unsigned id);
|
||||
root_region (symbol::id_t id);
|
||||
|
||||
enum region_kind get_kind () const final override { return RK_ROOT; }
|
||||
void dump_to_pp (pretty_printer *pp, bool simple) const final override;
|
||||
|
@ -661,7 +654,7 @@ public:
|
|||
const svalue *m_sval_ptr;
|
||||
};
|
||||
|
||||
symbolic_region (unsigned id, region *parent, const svalue *sval_ptr);
|
||||
symbolic_region (symbol::id_t id, region *parent, const svalue *sval_ptr);
|
||||
|
||||
const symbolic_region *
|
||||
dyn_cast_symbolic_region () const final override { return this; }
|
||||
|
@ -701,7 +694,7 @@ namespace ana {
|
|||
class decl_region : public region
|
||||
{
|
||||
public:
|
||||
decl_region (unsigned id, const region *parent, tree decl)
|
||||
decl_region (symbol::id_t id, const region *parent, tree decl)
|
||||
: region (complexity (parent), id, parent, TREE_TYPE (decl)), m_decl (decl),
|
||||
m_tracked (calc_tracked_p (decl)),
|
||||
m_ctor_svalue (NULL)
|
||||
|
@ -789,7 +782,7 @@ public:
|
|||
tree m_field;
|
||||
};
|
||||
|
||||
field_region (unsigned id, const region *parent, tree field)
|
||||
field_region (symbol::id_t id, const region *parent, tree field)
|
||||
: region (complexity (parent), id, parent, TREE_TYPE (field)),
|
||||
m_field (field)
|
||||
{}
|
||||
|
@ -871,7 +864,7 @@ public:
|
|||
const svalue *m_index;
|
||||
};
|
||||
|
||||
element_region (unsigned id, const region *parent, tree element_type,
|
||||
element_region (symbol::id_t id, const region *parent, tree element_type,
|
||||
const svalue *index)
|
||||
: region (complexity::from_pair (parent, index), id, parent, element_type),
|
||||
m_index (index)
|
||||
|
@ -958,7 +951,7 @@ public:
|
|||
const svalue *m_byte_offset;
|
||||
};
|
||||
|
||||
offset_region (unsigned id, const region *parent, tree type,
|
||||
offset_region (symbol::id_t id, const region *parent, tree type,
|
||||
const svalue *byte_offset)
|
||||
: region (complexity::from_pair (parent, byte_offset), id, parent, type),
|
||||
m_byte_offset (byte_offset)
|
||||
|
@ -1050,7 +1043,7 @@ public:
|
|||
const svalue *m_end_offset;
|
||||
};
|
||||
|
||||
sized_region (unsigned id, const region *parent, tree type,
|
||||
sized_region (symbol::id_t id, const region *parent, tree type,
|
||||
const svalue *byte_size_sval)
|
||||
: region (complexity::from_pair (parent, byte_size_sval),
|
||||
id, parent, type),
|
||||
|
@ -1139,7 +1132,7 @@ public:
|
|||
tree m_type;
|
||||
};
|
||||
|
||||
cast_region (unsigned id, const region *original_region, tree type)
|
||||
cast_region (symbol::id_t id, const region *original_region, tree type)
|
||||
: region (complexity (original_region), id,
|
||||
original_region->get_parent_region (), type),
|
||||
m_original_region (original_region)
|
||||
|
@ -1183,7 +1176,7 @@ namespace ana {
|
|||
class heap_allocated_region : public region
|
||||
{
|
||||
public:
|
||||
heap_allocated_region (unsigned id, const region *parent)
|
||||
heap_allocated_region (symbol::id_t id, const region *parent)
|
||||
: region (complexity (parent), id, parent, NULL_TREE)
|
||||
{}
|
||||
|
||||
|
@ -1198,7 +1191,7 @@ public:
|
|||
class alloca_region : public region
|
||||
{
|
||||
public:
|
||||
alloca_region (unsigned id, const frame_region *parent)
|
||||
alloca_region (symbol::id_t id, const frame_region *parent)
|
||||
: region (complexity (parent), id, parent, NULL_TREE)
|
||||
{}
|
||||
|
||||
|
@ -1212,7 +1205,7 @@ public:
|
|||
class string_region : public region
|
||||
{
|
||||
public:
|
||||
string_region (unsigned id, const region *parent, tree string_cst)
|
||||
string_region (symbol::id_t id, const region *parent, tree string_cst)
|
||||
: region (complexity (parent), id, parent, TREE_TYPE (string_cst)),
|
||||
m_string_cst (string_cst)
|
||||
{}
|
||||
|
@ -1290,7 +1283,7 @@ public:
|
|||
bit_range m_bits;
|
||||
};
|
||||
|
||||
bit_range_region (unsigned id, const region *parent, tree type,
|
||||
bit_range_region (symbol::id_t id, const region *parent, tree type,
|
||||
const bit_range &bits)
|
||||
: region (complexity (parent), id, parent, type),
|
||||
m_bits (bits)
|
||||
|
@ -1377,7 +1370,7 @@ public:
|
|||
unsigned m_idx;
|
||||
};
|
||||
|
||||
var_arg_region (unsigned id, const frame_region *parent,
|
||||
var_arg_region (symbol::id_t id, const frame_region *parent,
|
||||
unsigned idx)
|
||||
: region (complexity (parent), id, parent, NULL_TREE),
|
||||
m_idx (idx)
|
||||
|
@ -1420,7 +1413,7 @@ namespace ana {
|
|||
class errno_region : public region
|
||||
{
|
||||
public:
|
||||
errno_region (unsigned id, const thread_local_region *parent)
|
||||
errno_region (symbol::id_t id, const thread_local_region *parent)
|
||||
: region (complexity (parent), id, parent, integer_type_node)
|
||||
{}
|
||||
|
||||
|
@ -1446,7 +1439,7 @@ namespace ana {
|
|||
class unknown_region : public region
|
||||
{
|
||||
public:
|
||||
unknown_region (unsigned id, const region *parent, tree type)
|
||||
unknown_region (symbol::id_t id, const region *parent, tree type)
|
||||
: region (complexity (parent), id, parent, type)
|
||||
{}
|
||||
|
||||
|
|
|
@ -1254,10 +1254,12 @@ binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
|
|||
|
||||
/* sub_svalue'c ctor. */
|
||||
|
||||
sub_svalue::sub_svalue (tree type, const svalue *parent_svalue,
|
||||
sub_svalue::sub_svalue (symbol::id_t id,
|
||||
tree type, const svalue *parent_svalue,
|
||||
const region *subregion)
|
||||
: svalue (complexity::from_pair (parent_svalue->get_complexity (),
|
||||
subregion->get_complexity ()),
|
||||
id,
|
||||
type),
|
||||
m_parent_svalue (parent_svalue), m_subregion (subregion)
|
||||
{
|
||||
|
@ -1311,10 +1313,11 @@ sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
|
|||
|
||||
/* repeated_svalue'c ctor. */
|
||||
|
||||
repeated_svalue::repeated_svalue (tree type,
|
||||
repeated_svalue::repeated_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
const svalue *outer_size,
|
||||
const svalue *inner_svalue)
|
||||
: svalue (complexity::from_pair (outer_size, inner_svalue), type),
|
||||
: svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
|
||||
m_outer_size (outer_size),
|
||||
m_inner_svalue (inner_svalue)
|
||||
{
|
||||
|
@ -1438,10 +1441,11 @@ repeated_svalue::maybe_fold_bits_within (tree type,
|
|||
|
||||
/* bits_within_svalue'c ctor. */
|
||||
|
||||
bits_within_svalue::bits_within_svalue (tree type,
|
||||
bits_within_svalue::bits_within_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
const bit_range &bits,
|
||||
const svalue *inner_svalue)
|
||||
: svalue (complexity (inner_svalue), type),
|
||||
: svalue (complexity (inner_svalue), id, type),
|
||||
m_bits (bits),
|
||||
m_inner_svalue (inner_svalue)
|
||||
{
|
||||
|
@ -1736,8 +1740,10 @@ unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
|
|||
|
||||
/* class compound_svalue : public svalue. */
|
||||
|
||||
compound_svalue::compound_svalue (tree type, const binding_map &map)
|
||||
: svalue (calc_complexity (map), type), m_map (map)
|
||||
compound_svalue::compound_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
const binding_map &map)
|
||||
: svalue (calc_complexity (map), id, type), m_map (map)
|
||||
{
|
||||
#if CHECKING_P
|
||||
for (iterator_t iter = begin (); iter != end (); ++iter)
|
||||
|
|
|
@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#ifndef GCC_ANALYZER_SVALUE_H
|
||||
#define GCC_ANALYZER_SVALUE_H
|
||||
|
||||
#include "analyzer/complexity.h"
|
||||
#include "analyzer/symbol.h"
|
||||
#include "analyzer/store.h"
|
||||
#include "analyzer/program-point.h"
|
||||
|
||||
|
@ -86,7 +86,7 @@ enum svalue_kind
|
|||
|
||||
/* An abstract base class representing a value held by a region of memory. */
|
||||
|
||||
class svalue
|
||||
class svalue : public symbol
|
||||
{
|
||||
public:
|
||||
virtual ~svalue () {}
|
||||
|
@ -146,8 +146,6 @@ public:
|
|||
region_model_manager *mgr,
|
||||
model_merger *merger) const;
|
||||
|
||||
const complexity &get_complexity () const { return m_complexity; }
|
||||
|
||||
virtual void accept (visitor *v) const = 0;
|
||||
|
||||
bool live_p (const svalue_set *live_svalues,
|
||||
|
@ -180,12 +178,11 @@ public:
|
|||
const region *maybe_get_deref_base_region () const;
|
||||
|
||||
protected:
|
||||
svalue (complexity c, tree type)
|
||||
: m_complexity (c), m_type (type)
|
||||
svalue (complexity c, symbol::id_t id, tree type)
|
||||
: symbol (c, id), m_type (type)
|
||||
{}
|
||||
|
||||
private:
|
||||
complexity m_complexity;
|
||||
tree m_type;
|
||||
};
|
||||
|
||||
|
@ -224,8 +221,8 @@ public:
|
|||
const region *m_reg;
|
||||
};
|
||||
|
||||
region_svalue (tree type, const region *reg)
|
||||
: svalue (complexity (reg), type),
|
||||
region_svalue (symbol::id_t id, tree type, const region *reg)
|
||||
: svalue (complexity (reg), id, type),
|
||||
m_reg (reg)
|
||||
{
|
||||
gcc_assert (m_reg != NULL);
|
||||
|
@ -273,8 +270,8 @@ namespace ana {
|
|||
class constant_svalue : public svalue
|
||||
{
|
||||
public:
|
||||
constant_svalue (tree cst_expr)
|
||||
: svalue (complexity (1, 1), TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
|
||||
constant_svalue (symbol::id_t id, tree cst_expr)
|
||||
: svalue (complexity (1, 1), id, TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
|
||||
{
|
||||
gcc_assert (cst_expr);
|
||||
gcc_assert (CONSTANT_CLASS_P (cst_expr));
|
||||
|
@ -325,8 +322,8 @@ namespace ana {
|
|||
class unknown_svalue : public svalue
|
||||
{
|
||||
public:
|
||||
unknown_svalue (tree type)
|
||||
: svalue (complexity (1, 1), type)
|
||||
unknown_svalue (symbol::id_t id, tree type)
|
||||
: svalue (complexity (1, 1), id, type)
|
||||
{}
|
||||
|
||||
enum svalue_kind get_kind () const final override { return SK_UNKNOWN; }
|
||||
|
@ -394,8 +391,8 @@ public:
|
|||
tree m_type;
|
||||
};
|
||||
|
||||
poisoned_svalue (enum poison_kind kind, tree type)
|
||||
: svalue (complexity (1, 1), type), m_kind (kind) {}
|
||||
poisoned_svalue (enum poison_kind kind, symbol::id_t id, tree type)
|
||||
: svalue (complexity (1, 1), id, type), m_kind (kind) {}
|
||||
|
||||
enum svalue_kind get_kind () const final override { return SK_POISONED; }
|
||||
const poisoned_svalue *
|
||||
|
@ -502,8 +499,9 @@ public:
|
|||
};
|
||||
|
||||
setjmp_svalue (const setjmp_record &setjmp_record,
|
||||
tree type)
|
||||
: svalue (complexity (1, 1), type), m_setjmp_record (setjmp_record)
|
||||
symbol::id_t id,
|
||||
tree type)
|
||||
: svalue (complexity (1, 1), id, type), m_setjmp_record (setjmp_record)
|
||||
{}
|
||||
|
||||
enum svalue_kind get_kind () const final override { return SK_SETJMP; }
|
||||
|
@ -550,8 +548,8 @@ namespace ana {
|
|||
class initial_svalue : public svalue
|
||||
{
|
||||
public:
|
||||
initial_svalue (tree type, const region *reg)
|
||||
: svalue (complexity (reg), type), m_reg (reg)
|
||||
initial_svalue (symbol::id_t id, tree type, const region *reg)
|
||||
: svalue (complexity (reg), id, type), m_reg (reg)
|
||||
{
|
||||
gcc_assert (m_reg != NULL);
|
||||
}
|
||||
|
@ -624,8 +622,9 @@ public:
|
|||
const svalue *m_arg;
|
||||
};
|
||||
|
||||
unaryop_svalue (tree type, enum tree_code op, const svalue *arg)
|
||||
: svalue (complexity (arg), type), m_op (op), m_arg (arg)
|
||||
unaryop_svalue (symbol::id_t id, tree type, enum tree_code op,
|
||||
const svalue *arg)
|
||||
: svalue (complexity (arg), id, type), m_op (op), m_arg (arg)
|
||||
{
|
||||
gcc_assert (arg->can_have_associated_state_p ());
|
||||
}
|
||||
|
@ -713,11 +712,12 @@ public:
|
|||
const svalue *m_arg1;
|
||||
};
|
||||
|
||||
binop_svalue (tree type, enum tree_code op,
|
||||
const svalue *arg0, const svalue *arg1)
|
||||
binop_svalue (symbol::id_t id, tree type, enum tree_code op,
|
||||
const svalue *arg0, const svalue *arg1)
|
||||
: svalue (complexity::from_pair (arg0->get_complexity (),
|
||||
arg1->get_complexity ()),
|
||||
type),
|
||||
id,
|
||||
type),
|
||||
m_op (op), m_arg0 (arg0), m_arg1 (arg1)
|
||||
{
|
||||
gcc_assert (arg0->can_have_associated_state_p ());
|
||||
|
@ -802,8 +802,8 @@ public:
|
|||
const svalue *m_parent_svalue;
|
||||
const region *m_subregion;
|
||||
};
|
||||
sub_svalue (tree type, const svalue *parent_svalue,
|
||||
const region *subregion);
|
||||
sub_svalue (symbol::id_t id, tree type, const svalue *parent_svalue,
|
||||
const region *subregion);
|
||||
|
||||
enum svalue_kind get_kind () const final override { return SK_SUB; }
|
||||
const sub_svalue *dyn_cast_sub_svalue () const final override
|
||||
|
@ -883,7 +883,8 @@ public:
|
|||
const svalue *m_outer_size;
|
||||
const svalue *m_inner_svalue;
|
||||
};
|
||||
repeated_svalue (tree type,
|
||||
repeated_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
const svalue *outer_size,
|
||||
const svalue *inner_svalue);
|
||||
|
||||
|
@ -970,7 +971,8 @@ public:
|
|||
bit_range m_bits;
|
||||
const svalue *m_inner_svalue;
|
||||
};
|
||||
bits_within_svalue (tree type,
|
||||
bits_within_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
const bit_range &bits,
|
||||
const svalue *inner_svalue);
|
||||
|
||||
|
@ -1031,8 +1033,8 @@ namespace ana {
|
|||
class unmergeable_svalue : public svalue
|
||||
{
|
||||
public:
|
||||
unmergeable_svalue (const svalue *arg)
|
||||
: svalue (complexity (arg), arg->get_type ()), m_arg (arg)
|
||||
unmergeable_svalue (symbol::id_t id, const svalue *arg)
|
||||
: svalue (complexity (arg), id, arg->get_type ()), m_arg (arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1071,8 +1073,8 @@ namespace ana {
|
|||
class placeholder_svalue : public svalue
|
||||
{
|
||||
public:
|
||||
placeholder_svalue (tree type, const char *name)
|
||||
: svalue (complexity (1, 1), type), m_name (name)
|
||||
placeholder_svalue (symbol::id_t id, tree type, const char *name)
|
||||
: svalue (complexity (1, 1), id, type), m_name (name)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1155,10 +1157,11 @@ public:
|
|||
DIR_UNKNOWN
|
||||
};
|
||||
|
||||
widening_svalue (tree type, const function_point &point,
|
||||
widening_svalue (symbol::id_t id, tree type, const function_point &point,
|
||||
const svalue *base_sval, const svalue *iter_sval)
|
||||
: svalue (complexity::from_pair (base_sval->get_complexity (),
|
||||
iter_sval->get_complexity ()),
|
||||
id,
|
||||
type),
|
||||
m_point (point),
|
||||
m_base_sval (base_sval), m_iter_sval (iter_sval)
|
||||
|
@ -1260,7 +1263,7 @@ public:
|
|||
const binding_map *m_map_ptr;
|
||||
};
|
||||
|
||||
compound_svalue (tree type, const binding_map &map);
|
||||
compound_svalue (symbol::id_t id, tree type, const binding_map &map);
|
||||
|
||||
enum svalue_kind get_kind () const final override { return SK_COMPOUND; }
|
||||
const compound_svalue *dyn_cast_compound_svalue () const final override
|
||||
|
@ -1389,8 +1392,9 @@ public:
|
|||
const region *m_id_reg;
|
||||
};
|
||||
|
||||
conjured_svalue (tree type, const gimple *stmt, const region *id_reg)
|
||||
: svalue (complexity (id_reg), type),
|
||||
conjured_svalue (symbol::id_t id, tree type, const gimple *stmt,
|
||||
const region *id_reg)
|
||||
: svalue (complexity (id_reg), id, type),
|
||||
m_stmt (stmt), m_id_reg (id_reg)
|
||||
{
|
||||
gcc_assert (m_stmt != NULL);
|
||||
|
@ -1501,12 +1505,13 @@ public:
|
|||
const svalue *m_input_arr[MAX_INPUTS];
|
||||
};
|
||||
|
||||
asm_output_svalue (tree type,
|
||||
asm_output_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
const char *asm_string,
|
||||
unsigned output_idx,
|
||||
unsigned num_outputs,
|
||||
const vec<const svalue *> &inputs)
|
||||
: svalue (complexity::from_vec_svalue (inputs), type),
|
||||
: svalue (complexity::from_vec_svalue (inputs), id, type),
|
||||
m_asm_string (asm_string),
|
||||
m_output_idx (output_idx),
|
||||
m_num_outputs (num_outputs),
|
||||
|
@ -1634,10 +1639,11 @@ public:
|
|||
const svalue *m_input_arr[MAX_INPUTS];
|
||||
};
|
||||
|
||||
const_fn_result_svalue (tree type,
|
||||
const_fn_result_svalue (symbol::id_t id,
|
||||
tree type,
|
||||
tree fndecl,
|
||||
const vec<const svalue *> &inputs)
|
||||
: svalue (complexity::from_vec_svalue (inputs), type),
|
||||
: svalue (complexity::from_vec_svalue (inputs), id, type),
|
||||
m_fndecl (fndecl),
|
||||
m_num_inputs (inputs.length ())
|
||||
{
|
||||
|
|
43
gcc/analyzer/symbol.cc
Normal file
43
gcc/analyzer/symbol.cc
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* Base class for svalues and regions.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#define INCLUDE_MEMORY
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tree.h"
|
||||
#include "analyzer/analyzer.h"
|
||||
#include "analyzer/symbol.h"
|
||||
|
||||
#if ENABLE_ANALYZER
|
||||
|
||||
namespace ana {
|
||||
|
||||
/* Compare SYM1 and SYM2 by id. */
|
||||
|
||||
int
|
||||
symbol::cmp_ids (const symbol *sym1, const symbol *sym2)
|
||||
{
|
||||
return (long)sym1->get_id () - (long)sym2->get_id ();
|
||||
}
|
||||
|
||||
} // namespace ana
|
||||
|
||||
#endif /* #if ENABLE_ANALYZER */
|
53
gcc/analyzer/symbol.h
Normal file
53
gcc/analyzer/symbol.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* Base class for svalues and regions.
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
Contributed by David Malcolm <dmalcolm@redhat.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_ANALYZER_SYMBOL_H
|
||||
#define GCC_ANALYZER_SYMBOL_H
|
||||
|
||||
#include "analyzer/complexity.h"
|
||||
|
||||
namespace ana {
|
||||
|
||||
/* Base class for svalues and regions: has a complexity and a numeric ID. */
|
||||
|
||||
class symbol
|
||||
{
|
||||
public:
|
||||
typedef unsigned id_t;
|
||||
|
||||
const complexity &get_complexity () const { return m_complexity; }
|
||||
|
||||
id_t get_id () const { return m_id; }
|
||||
static int cmp_ids (const symbol *s1, const symbol *s2);
|
||||
|
||||
protected:
|
||||
symbol (complexity c, unsigned id)
|
||||
: m_complexity (c),
|
||||
m_id (id)
|
||||
{}
|
||||
|
||||
private:
|
||||
complexity m_complexity;
|
||||
id_t m_id; // for deterministic sorting at this stage, for dumps
|
||||
};
|
||||
|
||||
} // namespace ana
|
||||
|
||||
#endif /* GCC_ANALYZER_SYMBOL_H */
|
Loading…
Add table
Reference in a new issue