예제 #1
0
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);
    }
  }
}
예제 #2
0
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;
  }
}