Пример #1
0
void c_typecheck_baset::designator_enter(
  const typet &type,
  designatort &designator)
{
  designatort::entryt entry;
  entry.type=type;

  assert(entry.type.id()!=ID_symbol);
  
  if(entry.type.id()==ID_struct)
  {
    entry.size=to_struct_type(entry.type).components().size();

    if(entry.size!=0)
      entry.subtype=to_struct_type(entry.type).components().front().type();
    else
      entry.subtype.make_nil();
  }
  else if(entry.type.id()==ID_union)
  {
    if(to_union_type(entry.type).components().empty())
    {
      entry.size=0;
      entry.subtype.make_nil();
    }
    else
    {
      entry.size=1;
      entry.subtype=to_union_type(entry.type).components().front().type();
    }
  }
  else if(entry.type.id()==ID_array)
  {
    mp_integer array_size;

    if(to_integer(to_array_type(entry.type).size(), array_size))
    {
      err_location(to_array_type(entry.type).size());
      str << "array has non-constant size `"
          << to_string(to_array_type(entry.type).size()) << "'";
      throw 0;
    }

    entry.size=integer2long(array_size);
    entry.subtype=entry.type.subtype();
  }
  else if(entry.type.id()==ID_incomplete_array)
  {
    entry.size=0;
    entry.subtype=entry.type.subtype();
  }
  else
    assert(false);

  designator.push_entry(entry);
}
Пример #2
0
bool refined_string_typet::is_c_string_type(const typet &type)
{
  if (type.id() == ID_struct) {
    irep_idt tag = to_struct_type(type).get_tag();
    return (tag == irep_idt("__CPROVER_string"));
  } else return false;
}
Пример #3
0
void java_root_class(symbolt &class_symbol)
{
  struct_typet &struct_type=to_struct_type(class_symbol.type);
  struct_typet::componentst &components=struct_type.components();

  {
    // for monitorenter/monitorexit
    struct_typet::componentt component;
    component.set_name("@lock");
    component.set_pretty_name("@lock");
    component.type()=java_boolean_type();

    // add at the beginning
    components.insert(components.begin(), component);
  }

  {
    // the class identifier is used for stuff such as 'instanceof'
    struct_typet::componentt component;
    component.set_name("@class_identifier");
    component.set_pretty_name("@class_identifier");
    component.type()=string_typet();

    // add at the beginning
    components.insert(components.begin(), component);
  }
}
Пример #4
0
void java_bytecode_parsert::get_class_refs_rec(const typet &src)
{
  if(src.id()==ID_code)
  {
    const code_typet &ct=to_code_type(src);
    const typet &rt=ct.return_type();
    get_class_refs_rec(rt);
    for(const auto &p : ct.parameters())
      get_class_refs_rec(p.type());
  }
  else if(src.id()==ID_symbol)
  {
    irep_idt name=src.get(ID_C_base_name);
    if(has_prefix(id2string(name), "array["))
    {
      const typet &element_type=
        static_cast<const typet &>(src.find(ID_C_element_type));
      get_class_refs_rec(element_type);
    }
    else
      parse_tree.class_refs.insert(name);
  }
  else if(src.id()==ID_struct)
  {
    const struct_typet &struct_type=to_struct_type(src);
    for(const auto &c : struct_type.components())
      get_class_refs_rec(c.type());
  }
  else if(src.id()==ID_pointer)
    get_class_refs_rec(src.subtype());
}
Пример #5
0
bvt boolbvt::convert_struct(const struct_exprt &expr)
{
  const struct_typet &struct_type=to_struct_type(ns.follow(expr.type()));

  std::size_t width=boolbv_width(struct_type);

  const struct_typet::componentst &components=struct_type.components();

  if(expr.operands().size()!=components.size())
  {
    error().source_location=expr.find_source_location();
    error() << "struct: wrong number of arguments" << eom;
    throw 0;
  }

  bvt bv;
  bv.resize(width);

  std::size_t offset=0, i=0;

  for(struct_typet::componentst::const_iterator
      it=components.begin();
      it!=components.end();
      it++)
  {
    const typet &subtype=it->type();
    const exprt &op=expr.operands()[i];

    if(!base_type_eq(subtype, op.type(), ns))
    {
      error().source_location=expr.find_source_location();
      error() << "struct: component type does not match: "
              << subtype.pretty() << " vs. "
              << op.type().pretty() << eom;
      throw 0;
    }

    std::size_t subtype_width=boolbv_width(subtype);

    if(subtype_width!=0)
    {
      const bvt &op_bv=convert_bv(op);

      assert(offset<width);
      assert(op_bv.size()==subtype_width);
      assert(offset+op_bv.size()<=width);

      for(std::size_t j=0; j<op_bv.size(); j++)
        bv[offset+j]=op_bv[j];

      offset+=op_bv.size();
    }

    i++;
  }

  assert(offset==width);

  return bv;
}
Пример #6
0
exprt remove_virtual_functionst::build_class_identifier(
  const exprt &src)
{
  // the class identifier is in the root class
  exprt e=src;
  
  while(1)
  {
    const typet &type=ns.follow(e.type());
    assert(type.id()==ID_struct);
    
    const struct_typet &struct_type=to_struct_type(type);
    const struct_typet::componentst &components=struct_type.components();
    assert(!components.empty());
    
    member_exprt member_expr(
      e, components.front().get_name(), components.front().type());
    
    if(components.front().get_name()=="@class_identifier")
    {
      // found it
      return member_expr;
    }
    else
    {
      e=member_expr;
    }
  }
}
Пример #7
0
void boolbvt::convert_with(
  const typet &type,
  const exprt &op1,
  const exprt &op2,
  const bvt &prev_bv,
  bvt &next_bv)
{
  // we only do that on arrays, bitvectors, structs, and unions

  next_bv.resize(prev_bv.size());

  if(type.id()==ID_array)
    return convert_with_array(to_array_type(type), op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_bv ||
          type.id()==ID_unsignedbv ||
          type.id()==ID_signedbv)
    return convert_with_bv(type, op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_struct)
    return convert_with_struct(to_struct_type(type), op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_union)
    return convert_with_union(to_union_type(type), op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_symbol)
    return convert_with(ns.follow(type), op1, op2, prev_bv, next_bv);

  error().source_location=type.source_location();
  error() << "unexpected with type: " << type.id();
  throw 0;
}
Пример #8
0
void path_slicert::get_suffixes(
    const std::string &base,
    const typet &type,
    string_sett &s)
{
    const irep_idt &type_id=ns.follow(type).id();

    if(type_id==ID_struct || type_id==ID_union)
    {
        s.insert(base);

        const struct_typet &struct_type=to_struct_type(ns.follow(type));

        for(struct_typet::componentst::const_iterator
                c_it=struct_type.components().begin();
                c_it!=struct_type.components().end();
                c_it++)
        {
            const typet &subtype=c_it->type();
            const irep_idt &name=c_it->get(ID_name);
            get_suffixes(base+"."+id2string(name), subtype, s);
        }
    }
    else if(type_id==ID_array)
    {
        s.insert(base);
        get_suffixes(base+"[]", ns.follow(type).subtype(), s);
    }
    else
    {
        // no suffixes
        s.insert(base);
    }
}
Пример #9
0
bool refined_string_typet::is_java_deref_string_type(const typet &type)
{
  if(type.id() == ID_struct) {
    irep_idt tag = to_struct_type(type).get_tag();
    return (tag == irep_idt("java.lang.String"));
  } 
  else return false;
}
exprt remove_const_function_pointerst::get_component_value(
  const struct_exprt &struct_expr, const member_exprt &member_expr)
{
  const struct_typet &struct_type=to_struct_type(ns.follow(struct_expr.type()));
  size_t component_number=
    struct_type.component_number(member_expr.get_component_name());

  return struct_expr.operands()[component_number];
}
Пример #11
0
bool is_jsa_heap(const typet &type)
{
  const irep_idt &type_id=type.id();
  if (ID_symbol == type_id)
    return id2string(to_symbol_type(type).get_identifier()) == JSA_HEAP_TAG;
  if (ID_struct != type_id) return false;
  const irep_idt tag(to_struct_type(type).get_tag());
  return id2string(tag) == JSA_HEAP_TAG;
}
Пример #12
0
const exprt &get_controller_comp(const namespacet &ns,
    const struct_exprt &value, const char * const comp)
{
  const struct_typet &type=to_struct_type(ns.follow(value.type()));
  const struct_typet::componentst &comps=type.components();
  for (size_t i=0; i < comps.size(); ++i)
    if (id2string(comps[i].get_name()) == comp) return value.operands()[i];
  assert(!"Solution component not found.");
}
Пример #13
0
const struct_typet &cpp_typecheckt::this_struct_type()
{
  const exprt &this_expr = cpp_scopes.current_scope().this_expr;

  assert(this_expr.is_not_nil());
  assert(this_expr.type().id() == "pointer");

  const typet &t = follow(this_expr.type().subtype());
  return to_struct_type(t);
}
Пример #14
0
bool dereferencet::type_compatible(
  const typet &object_type,
  const typet &dereference_type) const
{
  if(dereference_type.id()==ID_empty)
    return true; // always ok

  if(base_type_eq(object_type, dereference_type, ns))
    return true; // ok, they just match

  // check for struct prefixes

  if(object_type.id()==ID_struct &&
     dereference_type.id()==ID_struct)
  {
    if(to_struct_type(dereference_type).is_prefix_of(
         to_struct_type(object_type)))
      return true; // ok, dreference_type is a prefix of object_type
  }

  // any code is ok
  if(dereference_type.id()==ID_code &&
     object_type.id()==ID_code)
    return true;

  // bit vectors of same size are ok
  if((object_type.id()==ID_signedbv || object_type.id()==ID_unsignedbv) &&
     (dereference_type.id()==ID_signedbv ||
      dereference_type.id()==ID_unsignedbv))
  {
    return object_type.get(ID_width)==dereference_type.get(ID_width);
  }

  // Any pointer to pointer is always ok,
  // but should likely check that width is the same.
  if(object_type.id()==ID_pointer &&
     dereference_type.id()==ID_pointer)
    return true;

  // really different

  return false;
}
void cpp_typecheckt::find_constructor(
  const typet &start_dest_type,
  exprt &constructor_expr)
{
  constructor_expr.make_nil();

  source_locationt source_location=start_dest_type.source_location();
  typet dest_type(start_dest_type);
  follow_symbol(dest_type);

  if(dest_type.id()!=ID_struct)
    return;

  const struct_typet::componentst &components=
    to_struct_type(dest_type).components();

  for(struct_typet::componentst::const_iterator
      it=components.begin();
      it!=components.end();
      it++)
  {
    const struct_typet::componentt &component=*it;
    const typet &type=component.type();

    if(type.find(ID_return_type).id()==ID_constructor)
    {
      const irept::subt &parameters=
        type.find(ID_parameters).get_sub();

      namespacet ns(symbol_table);

      if(parameters.size()==1)
      {
        const exprt &parameter=(exprt &)parameters.front();
        const typet &arg_type=parameter.type();

        if(arg_type.id()==ID_pointer &&
           type_eq(arg_type.subtype(), dest_type, ns))
        {
          // found!
          const irep_idt &identifier=
            component.get(ID_name);

          if(identifier=="")
            throw "constructor without identifier";

          constructor_expr=exprt(ID_symbol, type);
          constructor_expr.set(ID_identifier, identifier);
          constructor_expr.add_source_location()=source_location;
          return;
        }
      }
    }
  }
}
Пример #16
0
bool value_set_dereferencet::dereference_type_compare(
  const typet &object_type,
  const typet &dereference_type) const
{
  if(dereference_type.id()==ID_empty)
    return true; // always ok

  if(base_type_eq(object_type, dereference_type, ns))
    return true; // ok, they just match

  // check for struct prefixes

  const typet ot_base=ns.follow(object_type),
              dt_base=ns.follow(dereference_type);

  if(ot_base.id()==ID_struct &&
     dt_base.id()==ID_struct)
  {
    if(to_struct_type(dt_base).is_prefix_of(
         to_struct_type(ot_base)))
      return true; // ok, dt is a prefix of ot
  }

  // we are generous about code pointers
  if(dereference_type.id()==ID_code &&
     object_type.id()==ID_code)
    return true;

  // bitvectors of same width are ok
  if((dereference_type.id()==ID_signedbv ||
      dereference_type.id()==ID_unsignedbv) &&
     (object_type.id()==ID_signedbv ||
      object_type.id()==ID_unsignedbv) &&
     to_bitvector_type(dereference_type).get_width()==
     to_bitvector_type(object_type).get_width())
    return true;

  // really different

  return false;
}
Пример #17
0
bool refined_string_typet::is_java_char_sequence_type(const typet &type)
{
  if(type.id() == ID_pointer) {
    pointer_typet pt = to_pointer_type(type);
    typet subtype = pt.subtype();
    if(subtype.id() == ID_struct) {
      irep_idt tag = to_struct_type(subtype).get_tag();
      return (tag == irep_idt("java.lang.CharSequence"));
    } 
    else return false;
  } else return false;
}
mp_integer compute_pointer_offset(
  const namespacet &ns,
  const exprt &expr)
{
  if(expr.id()==ID_symbol)
    return 0;
  else if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);
    
    const typet &array_type=ns.follow(expr.op0().type());
    assert(array_type.id()==ID_array);

    mp_integer o=compute_pointer_offset(ns, expr.op0());
    
    if(o!=-1)
    {
      mp_integer sub_size=
        pointer_offset_size(ns, array_type.subtype());

      mp_integer i;

      if(sub_size!=0 && !to_integer(expr.op1(), i))
        return o+i*sub_size;
    }
      
    // don't know
  }
  else if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);
    const typet &type=ns.follow(expr.op0().type());
    
    assert(type.id()==ID_struct ||
           type.id()==ID_union);

    mp_integer o=compute_pointer_offset(ns, expr.op0());

    if(o!=-1)
    {    
      if(type.id()==ID_union)
        return o;
    
      return o+member_offset(
        ns, to_struct_type(type), expr.get(ID_component_name));
    }
  }
  else if(expr.id()==ID_string_constant)
    return 0;

  return -1; // don't know
}
Пример #19
0
/// \par parameters: a type
/// \return Boolean telling whether the type is that of java char sequence
bool refined_string_typet::is_java_char_sequence_type(const typet &type)
{
  if(type.id()==ID_pointer)
  {
    const pointer_typet &pt=to_pointer_type(type);
    const typet &subtype=pt.subtype();
    if(subtype.id()==ID_struct)
    {
      const irep_idt &tag=to_struct_type(subtype).get_tag();
      return tag=="java.lang.CharSequence";
    }
  }
  return false;
}
Пример #20
0
/// \par parameters: a type
/// \return Boolean telling whether the type is that of java string builder
bool refined_string_typet::is_java_string_builder_type(const typet &type)
{
  if(type.id()==ID_pointer)
  {
    const pointer_typet &pt=to_pointer_type(type);
    const typet &subtype=pt.subtype();
    if(subtype.id()==ID_struct)
    {
      irep_idt tag=to_struct_type(subtype).get_tag();
      return tag=="java.lang.StringBuilder";
    }
  }
  return false;
}
Пример #21
0
/// \par parameters: a type
/// \return Boolean telling whether the type is that of java string
bool refined_string_typet::is_java_string_type(const typet &type)
{
  if(type.id()==ID_symbol)
  {
    irep_idt tag=to_symbol_type(type).get_identifier();
    return tag=="java::java.lang.String";
  }
  else if(type.id()==ID_struct)
  {
    irep_idt tag=to_struct_type(type).get_tag();
    return tag=="java.lang.String";
  }
  return false;
}
Пример #22
0
void c_typecheck_baset::increment_designator(designatort &designator)
{
  assert(!designator.empty());

  while(true)
  {
    designatort::entryt &entry=designator[designator.size()-1];
    const typet &full_type=follow(entry.type);

    entry.index++;

    if(full_type.id()==ID_array &&
       to_array_type(full_type).size().is_nil())
      return; // we will keep going forever

    if(full_type.id()==ID_struct &&
       entry.index<entry.size)
    {
      // need to adjust subtype
      const struct_typet &struct_type=
        to_struct_type(full_type);
      const struct_typet::componentst &components=
        struct_type.components();
      assert(components.size()==entry.size);

      // we skip over any padding or code
      while(entry.index<entry.size &&
            (components[entry.index].get_is_padding() ||
             components[entry.index].type().id()==ID_code))
        entry.index++;

      if(entry.index<entry.size)
        entry.subtype=components[entry.index].type();
    }

    if(entry.index<entry.size)
      return; // done

    if(designator.size()==1)
      return; // done

    // pop entry
    designator.pop_entry();

    assert(!designator.empty());
  }
}
Пример #23
0
code_function_callt get_destructor(
  const namespacet &ns,
  const typet &type)
{
  if(type.id()==ID_symbol)
  {
    return get_destructor(ns, ns.follow(type));
  }
  else if(type.id()==ID_struct)
  {
    const struct_typet &struct_type=to_struct_type(type);

    const struct_typet::componentst &components=
      struct_type.components();

    for(struct_typet::componentst::const_iterator
        it=components.begin();
        it!=components.end();
        it++)
    {
      if(it->type().id()==ID_code)
      {
        const code_typet &code_type=to_code_type(it->type());
        
        if(code_type.return_type().id()==ID_destructor &&
           code_type.parameters().size()==1)
        {
          const typet &arg_type=code_type.parameters().front().type();
          
          if(arg_type.id()==ID_pointer &&
             ns.follow(arg_type.subtype())==type)
          {
            exprt symbol_expr(ID_symbol, it->type());
            symbol_expr.set(ID_identifier, it->get(ID_name));      

            code_function_callt function_call;
            function_call.function()=symbol_expr;
            
            return function_call;
          }
        }
      }
    }
  }

  return static_cast<const code_function_callt &>(get_nil_irep());
}
Пример #24
0
bool replace_symbolt::replace(typet &dest)
{
  if(dest.has_subtype())
    replace(dest.subtype());

  Forall_subtypes(it, dest)
    replace(*it);
    
  if(dest.id()=="struct" ||
     dest.id()=="union")
  {
    struct_typet &struct_type = to_struct_type(dest);    
    struct_typet::componentst &components = struct_type.components();
    for (struct_typet::componentst::iterator it = components.begin();
         it!=components.end();
         it++)
      replace(*it);
  } 
  else if(dest.is_code())
  {
    code_typet &code_type=to_code_type(dest);
    code_typet::argumentst &arguments=code_type.arguments();
    for (code_typet::argumentst::iterator it = arguments.begin();
         it!=arguments.end();
         it++)
      replace(*it);
  }
  
  if(dest.id()=="symbol")
  {
    type_mapt::const_iterator it=
      type_map.find(dest.identifier());

    if(it!=type_map.end())
    {
      dest=it->second;
      return false;
    }
  }

  return true;
}
Пример #25
0
void cpp_typecheckt::clean_up()
{
  context.Foreach_operand([this](symbolt &s) {
    if(s.type.get_bool("is_template"))
    {
      context.erase_symbol(s.name);
      return;
    }
    if(s.type.is_struct() || s.type.is_union())
    {
      struct_typet &struct_type = to_struct_type(s.type);

      const struct_typet::componentst &components = struct_type.components();

      struct_typet::componentst data_members;
      data_members.reserve(components.size());

      struct_typet::componentst &function_members = struct_type.methods();

      function_members.reserve(components.size());

      for(const auto &component : components)
      {
        if(component.get_bool("is_static") || component.is_type())
        {
          // skip it
        }
        else if(component.type().id() == "code")
        {
          function_members.push_back(component);
        }
        else
        {
          data_members.push_back(component);
        }
      }

      struct_type.components().swap(data_members);
    }
  });
}
Пример #26
0
void c_typecheck_baset::increment_designator(designatort &designator)
{
  assert(!designator.empty());

  while(true)
  {
    designatort::entryt &entry=designator[designator.size()-1];

    entry.index++;
    
    if(entry.type.id()==ID_incomplete_array)
      return; // we will keep going forever

    if(entry.type.id()==ID_struct &&
       entry.index<entry.size)
    {
      // need to adjust subtype
      const struct_typet &struct_type=
        to_struct_type(entry.type);
      const struct_typet::componentst &components=
        struct_type.components();
      assert(components.size()==entry.size);
      
      // we skip over padding
      if(components[entry.index].get_is_padding())
        entry.index++;

      if(entry.index<entry.size)
        entry.subtype=components[entry.index].type();
    }

    if(entry.index<entry.size) return; // done
    
    if(designator.size()==1) return; // done
    
    // pop entry
    designator.pop_entry();
    
    assert(!designator.empty());
  }
}
Пример #27
0
void set_class_identifier(
  struct_exprt &expr,
  const namespacet &ns,
  const symbol_typet &class_type)
{
  const struct_typet &struct_type=
    to_struct_type(ns.follow(expr.type()));
  const struct_typet::componentst &components=struct_type.components();

  if(components.empty()) return;
  assert(!expr.operands().empty());
  
  if(components.front().get_name()=="@class_identifier")
  {
    assert(expr.op0().id()==ID_constant);
    expr.op0()=constant_exprt(class_type.get_identifier(), string_typet());
  }
  else
  {
    assert(expr.op0().id()==ID_struct);
    set_class_identifier(to_struct_expr(expr.op0()), ns, class_type);
  }
}
Пример #28
0
void invariant_propagationt::get_objects_rec(
  const exprt &src,
  std::list<exprt> &dest)
{
  const typet &t=ns.follow(src.type());

  if(t.id()==ID_struct ||
     t.id()==ID_union)
  {
    const struct_typet &struct_type=to_struct_type(t);
    
    const struct_typet::componentst &c=struct_type.components();
    
    exprt member_expr(ID_member);
    member_expr.copy_to_operands(src);
    
    for(struct_typet::componentst::const_iterator
        it=c.begin();
        it!=c.end();
        it++)
    {
      member_expr.set(ID_component_name, it->get_string(ID_name));
      member_expr.type()=it->type();
      // recursive call
      get_objects_rec(member_expr, dest);
    }
  }
  else if(t.id()==ID_array)
  {
    //get_objects_rec(identifier, suffix+"[]", t.subtype(), dest);
    //we don't track these
  }
  else if(check_type(t))
  {
    dest.push_back(src);
  }
}
Пример #29
0
void value_set_analysis_fivrt::get_entries_rec(
  const irep_idt &identifier,
  const std::string &suffix,
  const typet &type,
  std::list<value_set_fivrt::entryt> &dest)
{
  const typet &t=ns.follow(type);

  if(t.id()==ID_struct ||
     t.id()==ID_union)
  {
    const struct_typet &struct_type=to_struct_type(t);

    const struct_typet::componentst &c=struct_type.components();

    for(struct_typet::componentst::const_iterator
        it=c.begin();
        it!=c.end();
        it++)
    {
      get_entries_rec(
        identifier,
        suffix+"."+it->get_string(ID_name),
        it->type(),
        dest);
    }
  }
  else if(t.id()==ID_array)
  {
    get_entries_rec(identifier, suffix+"[]", t.subtype(), dest);
  }
  else if(check_type(t))
  {
    dest.push_back(value_set_fivrt::entryt(identifier, suffix));
  }
}
Пример #30
0
#include <util/std_types.h>
#include <util/symbol_table.h>

/// Looks for all the struct types in the symbol table and construct a map from
/// class names to a data structure that contains lists of parent and child
/// classes for each struct type (ie class).
/// \param symbol_table: The symbol table to analyze
void class_hierarchyt::operator()(const symbol_tablet &symbol_table)
{
  forall_symbols(it, symbol_table.symbols)
  {
    if(it->second.is_type && it->second.type.id()==ID_struct)
    {
      const struct_typet &struct_type=
        to_struct_type(it->second.type);

      const irept::subt &bases=
        struct_type.find(ID_bases).get_sub();

      for(const auto &base : bases)
      {
        irep_idt parent=base.find(ID_type).get(ID_identifier);
        if(parent.empty())
          continue;

        class_map[parent].children.push_back(it->first);
        class_map[it->first].parents.push_back(parent);
      }
    }
  }