diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc index c864a8fbc21..dfd2413e914 100644 --- a/gcc/analyzer/region-model-manager.cc +++ b/gcc/analyzer/region-model-manager.cc @@ -249,6 +249,10 @@ region_model_manager::get_or_create_initial_value (const region *reg) get_or_create_initial_value (original_reg)); } + /* INIT_VAL (*UNKNOWN_PTR) -> UNKNOWN_VAL. */ + if (reg->symbolic_for_unknown_ptr_p ()) + return get_or_create_unknown_svalue (reg->get_type ()); + if (initial_svalue **slot = m_initial_values_map.get (reg)) return *slot; initial_svalue *initial_sval = new initial_svalue (reg->get_type (), reg); @@ -815,6 +819,15 @@ region_model_manager::get_field_region (const region *parent, tree field) { gcc_assert (TREE_CODE (field) == FIELD_DECL); + /* (*UNKNOWN_PTR).field is (*UNKNOWN_PTR_OF_&FIELD_TYPE). */ + if (parent->symbolic_for_unknown_ptr_p ()) + { + tree ptr_to_field_type = build_pointer_type (TREE_TYPE (field)); + const svalue *unknown_ptr_to_field + = get_or_create_unknown_svalue (ptr_to_field_type); + return get_symbolic_region (unknown_ptr_to_field); + } + field_region::key_t key (parent, field); if (field_region *reg = m_field_regions.get (key)) return reg; diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98918.c b/gcc/testsuite/gcc.dg/analyzer/pr98918.c new file mode 100644 index 00000000000..ac626ba1f30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr98918.c @@ -0,0 +1,22 @@ +#include + +struct marker { + struct marker *next; + void *ref; +}; +struct data { + struct marker *marker; +}; + +void data_free(struct data d) +{ + struct marker *nm, *m; + + m = d.marker; + while (m) { + nm = m->next; + free(m->ref); + free(m); + m = nm; + } +}