void rd_range_domaint::assign_dereference( const namespacet &ns, locationt from, const dereference_exprt &deref, const mp_integer &size) { assert(local_may_alias); const exprt &pointer=deref.pointer(); std::set<exprt> alias_set=local_may_alias->get(from, pointer); valuest before(values); for(std::set<exprt>::const_iterator it=alias_set.begin(); it!=alias_set.end(); it++) { if(it->id()!=ID_unknown && it->id()!=ID_dynamic_object && it->id()!=ID_null_object) { valuest bak; bak.swap(values); values=before; assign(ns, from, *it, size); rd_range_domaint this_object; this_object.values.swap(values); values.swap(bak); merge(this_object, from); } } }
void goto_checkt::pointer_validity_check( const dereference_exprt &expr, const guardt &guard) { if(!enable_pointer_check) return; const exprt &pointer=expr.op0(); const typet &pointer_type=to_pointer_type(ns.follow(pointer.type())); assert(base_type_eq(pointer_type.subtype(), expr.type(), ns)); local_bitvector_analysist::flagst flags= local_bitvector_analysis->get(t, pointer); const typet &dereference_type=pointer_type.subtype(); // For Java, we only need to check for null if(mode==ID_java) { if(flags.is_unknown() || flags.is_null()) { notequal_exprt not_eq_null(pointer, gen_zero(pointer.type())); add_guarded_claim( not_eq_null, "reference is null", "pointer dereference", expr.find_source_location(), expr, guard); } } else { if(flags.is_unknown() || flags.is_null()) { add_guarded_claim( not_exprt(null_pointer(pointer)), "dereference failure: pointer NULL", "pointer dereference", expr.find_source_location(), expr, guard); } if(flags.is_unknown()) add_guarded_claim( not_exprt(invalid_pointer(pointer)), "dereference failure: pointer invalid", "pointer dereference", expr.find_source_location(), expr, guard); if(flags.is_uninitialized()) add_guarded_claim( not_exprt(invalid_pointer(pointer)), "dereference failure: pointer uninitialized", "pointer dereference", expr.find_source_location(), expr, guard); if(mode != ID_java) { if(flags.is_unknown() || flags.is_dynamic_heap()) add_guarded_claim( not_exprt(deallocated(pointer, ns)), "dereference failure: deallocated dynamic object", "pointer dereference", expr.find_source_location(), expr, guard); if(flags.is_unknown() || flags.is_dynamic_local()) add_guarded_claim( not_exprt(dead_object(pointer, ns)), "dereference failure: dead object", "pointer dereference", expr.find_source_location(), expr, guard); } if(enable_bounds_check) { if(flags.is_unknown() || flags.is_dynamic_heap()) { exprt dynamic_bounds= or_exprt(dynamic_object_lower_bound(pointer), dynamic_object_upper_bound(pointer, dereference_type, ns)); add_guarded_claim( implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)), "dereference failure: dynamic object bounds", "pointer dereference", expr.find_source_location(), expr, guard); } } if(enable_bounds_check) { if(flags.is_unknown() || flags.is_dynamic_local() || flags.is_static_lifetime()) { exprt object_bounds= or_exprt(object_lower_bound(pointer), object_upper_bound(pointer, dereference_type, ns)); add_guarded_claim( or_exprt(dynamic_object(pointer), not_exprt(object_bounds)), "dereference failure: object bounds", "pointer dereference", expr.find_source_location(), expr, guard); } } } }
bool remove_const_function_pointerst::try_resolve_dereference( const dereference_exprt &deref_expr, expressionst &out_expressions, bool &out_is_const) { // We had a pointer, we need to check both the pointer // type can't be changed, and what it what pointing to // can't be changed expressionst pointer_values; bool pointer_const; bool resolved= try_resolve_expression(deref_expr.pointer(), pointer_values, pointer_const); if(resolved && pointer_const) { bool all_objects_const=true; for(const exprt &pointer_val : pointer_values) { if(pointer_val.id()==ID_address_of) { address_of_exprt address_expr=to_address_of_expr(pointer_val); bool object_const=false; expressionst out_object_values; bool resolved= try_resolve_expression( address_expr.object(), out_object_values, object_const); if(resolved) { out_expressions.insert( out_expressions.end(), out_object_values.begin(), out_object_values.end()); all_objects_const&=object_const; } else { LOG("Failed to resolve value of a dereference", address_expr); } } else { LOG( "Squashing dereference did not result in an address", pointer_val); return false; } } out_is_const=all_objects_const; return true; } else { if(!resolved) { LOG("Failed to resolve pointer of dereference", deref_expr); } else if(!pointer_const) { LOG("Pointer value not const so can't squash", deref_expr); } return false; } }