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).
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r14-2793-g9d804f9b2709b3. 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. --- gcc/Makefile.in | 1 + gcc/analyzer/region-model-manager.cc | 100 +++++++++++++++------------ gcc/analyzer/region-model-manager.h | 9 +-- gcc/analyzer/region-model.cc | 21 ++++-- gcc/analyzer/region.cc | 19 ++--- gcc/analyzer/region.h | 61 ++++++++-------- gcc/analyzer/svalue.cc | 20 ++++-- gcc/analyzer/svalue.h | 86 ++++++++++++----------- gcc/analyzer/symbol.cc | 43 ++++++++++++ gcc/analyzer/symbol.h | 53 ++++++++++++++ 10 files changed, 263 insertions(+), 150 deletions(-) create mode 100644 gcc/analyzer/symbol.cc create mode 100644 gcc/analyzer/symbol.h diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 683774ad446..e99628cec07 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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 diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index e43b99ae0ba..46d271a295c 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -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); diff --git a/gcc/analyzer/region-model-manager.h b/gcc/analyzer/region-model-manager.h index ff5333bf07c..a5281819a69 100644 --- a/gcc/analyzer/region-model-manager.h +++ b/gcc/analyzer/region-model-manager.h @@ -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; diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index e01b1c88299..5ed735dc2a2 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -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); diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index 62ae0b2342d..9524739c7a4 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -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 () diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h index 2cbb9234728..47242385fd1 100644 --- a/gcc/analyzer/region.h +++ b/gcc/analyzer/region.h @@ -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) {} diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc index 1444274ad7a..4395018dbc3 100644 --- a/gcc/analyzer/svalue.cc +++ b/gcc/analyzer/svalue.cc @@ -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) diff --git a/gcc/analyzer/svalue.h b/gcc/analyzer/svalue.h index c8c3258d6bc..fbb10187677 100644 --- a/gcc/analyzer/svalue.h +++ b/gcc/analyzer/svalue.h @@ -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 ()) { diff --git a/gcc/analyzer/symbol.cc b/gcc/analyzer/symbol.cc new file mode 100644 index 00000000000..2d8624508fb --- /dev/null +++ b/gcc/analyzer/symbol.cc @@ -0,0 +1,43 @@ +/* Base class for svalues and regions. + Copyright (C) 2023 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalc...@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 */ diff --git a/gcc/analyzer/symbol.h b/gcc/analyzer/symbol.h new file mode 100644 index 00000000000..dbaf760f413 --- /dev/null +++ b/gcc/analyzer/symbol.h @@ -0,0 +1,53 @@ +/* Base class for svalues and regions. + Copyright (C) 2023 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalc...@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 */ -- 2.26.3