Example #1
0
pointer_logict::pointer_logict(const namespacet &_ns):ns(_ns)
{
  // add NULL
  null_object=objects.number(exprt(ID_NULL));
  assert(null_object==0);

  // add INVALID
  invalid_object=objects.number(exprt("INVALID"));
}
Example #2
0
exprt pointer_logict::pointer_expr(
  const pointert &pointer,
  const typet &type) const
{
  if(pointer.object==null_object) // NULL?
  {
    if(pointer.offset==0)
    {
      constant_exprt result(type);
      result.set_value(ID_NULL);
      return result;
    }
    else
    {
      constant_exprt null(type);
      null.set_value(ID_NULL);
      return plus_exprt(null,
        from_integer(pointer.offset, pointer_diff_type()));
    }
  }
  else if(pointer.object==invalid_object) // INVALID?
  {
    constant_exprt result(type);
    result.set_value("INVALID");
    return result;
  }

  if(pointer.object>=objects.size())
  {
    constant_exprt result(type);
    result.set_value("INVALID-"+std::to_string(pointer.object));
    return result;
  }

  const exprt &object_expr=objects[pointer.object];

  exprt deep_object=object_rec(pointer.offset, type, object_expr);

  exprt result;

  if(type.id()==ID_pointer)
    result=exprt(ID_address_of, type);
  else if(type.id()==ID_reference)
    result=exprt("reference_to", type);
  else
    assert(0);

  result.copy_to_operands(deep_object);
  return result;
}
Example #3
0
void xml_typecheckt::convert_xmi_class(const xmlt &xml)
{
  const xmlt &class_name=
    get(xml, "Foundation.Core.ModelElement.name");

  const xmlt &Ns=
    get(xml, "Foundation.Core.Namespace.ownedElement");

  symbolt symbol;

  symbol.base_name=class_name.data;
  symbol.name="xml::xmi::class::"+id2string(symbol.base_name);
  symbol.type=typet("class");

  for(xmlt::elementst::const_iterator
      n_it=Ns.elements.begin();
      n_it!=Ns.elements.end();
      n_it++)
  {
    if(n_it->name=="Behavioral_Elements.State_Machines.StateMachine")
    {
      symbol.value.copy_to_operands(exprt());     
      convert_xmi_StateMachine(*n_it, symbol.value.operands().back());
    }
    else
      throw "unexpected XMI: "+n_it->name;
  }

  if(symbol_table.move(symbol))
  {
    str << "class already in symbol table: " << symbol.name;
    throw 0;
  }
}
Example #4
0
void modelchecker_smvt::instantiate_expression(exprt &expr)
{
  Forall_operands(it, expr)
    instantiate_expression(*it);

  if(expr.id()==ID_predicate_symbol)
  {
    unsigned p=atoi(expr.get(ID_identifier).c_str());
    expr.id(ID_symbol);
    expr.set(ID_identifier, variable_names[p]);
  }
  else if(expr.id()==ID_predicate_next_symbol)
  {
    unsigned p=atoi(expr.get(ID_identifier).c_str());
    expr.id(ID_next_symbol);
    expr.set(ID_identifier, variable_names[p]);
  }
  else if(expr.id()==ID_nondet_symbol)
  {
    nondet_symbolst::const_iterator it=
      nondet_symbols.find(
        static_cast<const exprt &>(expr.find("expression")));

    if(it==nondet_symbols.end())
      throw "failed to find nondet_symbol";

    typet type=expr.type();
    expr=exprt(ID_symbol, type);
    expr.set(ID_identifier, it->second);
  }
}
Example #5
0
void cpp_typecheckt::new_temporary(
  const source_locationt &source_location,
  const typet &type,
  const exprt::operandst &ops,
  exprt &temporary)
{
  // create temporary object
  exprt tmp_object_expr=exprt(ID_side_effect, type);
  tmp_object_expr.set(ID_statement, ID_temporary_object);
  tmp_object_expr.add_source_location()= source_location;

  exprt new_object(ID_new_object);
  new_object.add_source_location()=tmp_object_expr.source_location();
  new_object.set(ID_C_lvalue, true);
  new_object.type()=tmp_object_expr.type();

  already_typechecked(new_object);

  codet new_code =
    cpp_constructor(source_location, new_object, ops);

  if(new_code.is_not_nil())
  {
    if(new_code.get(ID_statement)==ID_assign)
      tmp_object_expr.move_to_operands(new_code.op1());
    else
      tmp_object_expr.add(ID_initializer)=new_code;
  }

  temporary.swap(tmp_object_expr);
}
Example #6
0
void c_typecastt::implicit_typecast_arithmetic(
  exprt &expr,
  c_typet c_type)
{
  typet new_type;
  
  const typet &expr_type=ns.follow(expr.type());
  
  switch(c_type)
  {
  case PTR:
    if(expr_type.id()==ID_array)
    {
      new_type.id(ID_pointer);
      new_type.subtype()=expr_type.subtype();
      break;
    }
    return;

  case BOOL:       new_type=bool_typet(); break;
  case CHAR:       assert(false); // should always be promoted to int
  case UCHAR:      assert(false); // should always be promoted to int
  case SHORT:      assert(false); // should always be promoted to int
  case USHORT:     assert(false); // should always be promoted to int
  case INT:        new_type=int_type(); break;
  case UINT:       new_type=uint_type(); break;
  case LONG:       new_type=long_int_type(); break;
  case ULONG:      new_type=long_uint_type(); break;
  case LONGLONG:   new_type=long_long_int_type(); break;
  case ULONGLONG:  new_type=long_long_uint_type(); break;
  case SINGLE:     new_type=float_type(); break;
  case DOUBLE:     new_type=double_type(); break;
  case LONGDOUBLE: new_type=long_double_type(); break;
  case RATIONAL:   new_type=rational_typet(); break;
  case REAL:       new_type=real_typet(); break;
  case INTEGER:    new_type=integer_typet(); break;
  case COMPLEX: return; // do nothing
  default: return;
  }

  if(new_type!=expr_type)
  {
    if(new_type.id()==ID_pointer &&
       expr_type.id()==ID_array)
    {
      exprt index_expr(ID_index, expr_type.subtype());
      index_expr.reserve_operands(2);
      index_expr.move_to_operands(expr);
      index_expr.copy_to_operands(gen_zero(index_type()));
      expr=exprt(ID_address_of, new_type);
      expr.move_to_operands(index_expr);
    }
    else
      do_typecast(expr, new_type);
  }
}
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;
        }
      }
    }
  }
}
Example #8
0
void goto_symext::symex_dead(statet &state)
{
    const goto_programt::instructiont &instruction=*state.source.pc;

    const codet &code=to_code(instruction.code);

    if(code.operands().size()!=1)
        throw "dead expects one operand";

    if(code.op0().id()!=ID_symbol)
        throw "dead expects symbol as first operand";

    // We increase the L2 renaming to make these non-deterministic.
    // We also prevent propagation of old values.

    ssa_exprt ssa(to_symbol_expr(code.op0()));
    state.rename(ssa, ns, goto_symex_statet::L1);

    // in case of pointers, put something into the value set
    if(ns.follow(code.op0().type()).id()==ID_pointer)
    {
        exprt failed=
            get_failed_symbol(to_symbol_expr(code.op0()), ns);

        exprt rhs;

        if(failed.is_not_nil())
        {
            address_of_exprt address_of_expr;
            address_of_expr.object()=failed;
            address_of_expr.type()=code.op0().type();
            rhs=address_of_expr;
        }
        else
            rhs=exprt(ID_invalid);

        state.rename(rhs, ns, goto_symex_statet::L1);
        state.value_set.assign(ssa, rhs, ns, true, false);
    }

    ssa_exprt ssa_lhs=to_ssa_expr(ssa);
    const irep_idt &l1_identifier=ssa_lhs.get_identifier();

    // prevent propagation
    state.propagation.remove(l1_identifier);

    // L2 renaming
    if(state.level2.current_names.find(l1_identifier)!=
            state.level2.current_names.end())
        state.level2.increase_counter(l1_identifier);
}
Example #9
0
exprt c_typecheck_baset::do_initializer_list(
  const exprt &value,
  const typet &type,
  bool force_constant)
{
  assert(value.id()==ID_initializer_list);

  if(type.id()==ID_symbol)
    return do_initializer_list(
      value, follow(type), force_constant);

  exprt result;
  if(type.id()==ID_struct ||
     type.id()==ID_array ||
     type.id()==ID_union)
  {
    // start with zero everywhere
    result=zero_initializer(type, value.location());
  }
  else if(type.id()==ID_incomplete_array)
  {
    // start with empty array
    result=exprt(ID_array, type);
    result.location()=value.location();
  }
  else
  {
    // The initializer for a scalar shall be a single expression,
    // * optionally enclosed in braces. *

    if(value.operands().size()==1)
      return do_initializer_rec(value.op0(), type, force_constant);
    
    err_location(value);
    str << "cannot initialize `" << to_string(type) << "' with "
           "an initializer list";
    throw 0;
  }

  designatort current_designator;
  
  designator_enter(type, current_designator);
    
  forall_operands(it, value)
  {
    do_designated_initializer(
      result, current_designator, *it, force_constant);

    // increase designator -- might go up    
    increment_designator(current_designator);
  }
Example #10
0
void xml_typecheckt::convert_xmi_StateMachine(
  const xmlt &xml,
  exprt &dest)
{
  dest=exprt("StateMachine");

//  const xmlt &top=
//    get(xml, "Behavioral_Elements.State_Machines.StateMachine.top");

//  const xmlt &transitions=
//    get(xml, "Behavioral_Elements.State_Machines.StateMachine.transitions");


}
Example #11
0
exprt gen_one(const typet &type)
{
  const irep_idt type_id=type.id();
  exprt result=constant_exprt(type);

  if(type_id==ID_bool ||
     type_id==ID_rational ||
     type_id==ID_real ||
     type_id==ID_integer ||
     type_id==ID_natural)
  {
    result.set(ID_value, ID_1);
  }
  else if(type_id==ID_unsignedbv ||
          type_id==ID_signedbv ||
          type_id==ID_c_enum)
  {
    std::string value;
    unsigned width=to_bitvector_type(type).get_width();
    for(unsigned i=0; i<width-1; i++)
      value+='0';
    value+='1';
    result.set(ID_value, value);
  }
  else if(type_id==ID_fixedbv)
  {
    fixedbvt fixedbv;
    fixedbv.spec=to_fixedbv_type(type);
    fixedbv.from_integer(1);
    result=fixedbv.to_expr();
  }
  else if(type_id==ID_floatbv)
  {
    ieee_floatt ieee_float;
    ieee_float.spec=to_floatbv_type(type);
    ieee_float.from_integer(1);
    result=ieee_float.to_expr();
  }
  else if(type_id==ID_complex)
  {
    result=exprt(ID_complex, type);
    result.operands().resize(2);
    result.op0()=gen_one(type.subtype());
    result.op1()=gen_zero(type.subtype());
  }
  else
    result.make_nil();

  return result;
}
Example #12
0
exprt gen_zero(const typet &type)
{
  exprt result;

  const irep_idt type_id=type.id();

  result=constant_exprt(type);

  if(type_id==ID_rational ||
     type_id==ID_real ||
     type_id==ID_integer ||
     type_id==ID_natural ||
     type_id==ID_complex ||
     type_id==ID_c_enum)
  {
    result.set(ID_value, ID_0);
  }
  else if(type_id==ID_unsignedbv ||
          type_id==ID_signedbv ||
          type_id==ID_verilogbv ||
          type_id==ID_floatbv ||
          type_id==ID_fixedbv)
  {
    std::string value;
    unsigned width=to_bitvector_type(type).get_width();

    for(unsigned i=0; i<width; i++)
      value+='0';

    result.set(ID_value, value);
  }
  else if(type_id==ID_complex)
  {
    result=exprt(ID_complex, type);
    exprt sub_zero=gen_zero(type.subtype());
    result.operands().resize(2, sub_zero);
  }
  else if(type_id==ID_bool)
  {
    result.make_false();
  }
  else if(type_id==ID_pointer)
  {
    result.set(ID_value, ID_NULL);
  }
  else
    result.make_nil();

  return result;
}
Example #13
0
void goto_checkt::add_guarded_claim(
  const exprt &_expr,
  const std::string &comment,
  const std::string &property_class,
  const source_locationt &source_location,
  const exprt &src_expr,
  const guardt &guard)
{
  exprt expr(_expr);

  // first try simplifier on it
  if(enable_simplify)
    simplify(expr, ns);

  // throw away trivial properties?
  if(!retain_trivial && expr.is_true())
    return;

  // add the guard
  exprt guard_expr=guard.as_expr();

  exprt new_expr;

  if(guard_expr.is_true())
    new_expr.swap(expr);
  else
  {
    new_expr=exprt(ID_implies, bool_typet());
    new_expr.move_to_operands(guard_expr, expr);
  }

  if(assertions.insert(new_expr).second)
  {
    goto_program_instruction_typet type=
      enable_assert_to_assume?ASSUME:ASSERT;

    goto_programt::targett t=new_code.add_instruction(type);

    std::string source_expr_string=from_expr(ns, "", src_expr);

    t->guard.swap(new_expr);
    t->source_location=source_location;
    t->source_location.set_comment(comment+" in "+source_expr_string);
    t->source_location.set_property_class(property_class);
  }
}
Example #14
0
exprt guardt::as_expr(guard_listt::const_iterator it) const
{
  if(it==guard_list.end())
    return true_exprt();
  else if(it==--guard_list.end())
    return guard_list.back();

  exprt dest;
  dest=exprt(ID_and, typet(ID_bool));
  dest.reserve_operands(guard_list.size());
  for(; it!=guard_list.end(); it++)
  {
    if(!it->is_boolean())
      throw "guard is expected to be Boolean";
    dest.copy_to_operands(*it);
  }

  return dest;
}
Example #15
0
void goto_checkt::add_guarded_claim(const exprt &_expr,
    const std::string &comment, const std::string &property,
    const locationt &location, const guardt &guard)
{
  bool all_claims = options.get_bool_option("all-claims");
  exprt expr(_expr);

  // first try simplifier on it
  if (!options.get_bool_option("no-simplify"))
  {
    expr2tc tmpexpr;
    migrate_expr(expr, tmpexpr);
    base_type(tmpexpr, ns);
    expr = migrate_expr_back(tmpexpr);
    simplify(expr);
  }

  if (!all_claims && expr.is_true())
    return;

  // add the guard
  exprt guard_expr = migrate_expr_back(guard.as_expr());

  exprt new_expr;

  if (guard_expr.is_true())
    new_expr.swap(expr);
  else
  {
    new_expr = exprt("=>", bool_typet());
    new_expr.move_to_operands(guard_expr, expr);
  }

  if (assertions.insert(new_expr).second)
  {
    goto_programt::targett t = new_code.add_instruction(ASSERT);
    migrate_expr(new_expr, t->guard);

    t->location = location;
    t->location.comment(comment);
    t->location.property(property);
  }
}
Example #16
0
exprt gen_zero(const typet &type)
{
  exprt result;

  const std::string type_id=type.id_string();

  result=exprt("constant", type);

  if(type_id=="rational" ||
     type_id=="real" ||
     type_id=="integer" ||
     type_id=="natural" ||
     type_id=="complex")
  {
    result.value("0");
  }
  else if(type_id=="unsignedbv" ||
          type_id=="signedbv" ||
          type_id=="floatbv" ||
          type_id=="fixedbv" ||
          type_id=="c_enum")
  {
    std::string value;
    unsigned width=bv_width(type);

    for(unsigned i=0; i<width; i++)
      value+='0';

    result.value(value);
  }
  else if(type_id=="bool")
  {
    result.make_false();
  }
  else if(type_id=="pointer")
  {
    result.value("NULL");
  }
  else
    result.make_nil();

  return result;
}
Example #17
0
const exprt qbf_squolem_coret::f_get_dnf(WitnessStack *wsp)
{
  Clause *p=wsp->posWits;

  if(!p) return exprt(ID_false, typet(ID_bool));

  exprt::operandst operands;

  while(p!=NULL)
  {
    exprt cube=and_exprt();

    for(unsigned i=0; i<p->size; i++)
    {
      const Literal &lit=p->literals[i];
      exprt subf = f_get(literalt(var(lit), !isPositive(lit)));
      if(find(cube.operands().begin(), cube.operands().end(), subf)==
         cube.operands().end())
        cube.move_to_operands(subf);

      simplify_extractbits(cube);
    }

    if(cube.operands().empty())
      cube=true_exprt();
    else if(cube.operands().size()==1)
    {
      const exprt tmp=cube.op0();
      cube=tmp;
    }

    #if 0
    std::cout << "CUBE: " << cube << std::endl;
    #endif

    operands.push_back(cube);

    p=p->next;
  }

  return or_exprt(operands);
}
Example #18
0
exprt ranking_synthesis_satt::coefficient(const exprt &expr)
{
  assert(expr.id()==ID_symbol);

  exprt &entry = coefficient_map[expr];

  if(entry==exprt())
  {
    irep_idt ident=expr.get_string(ID_identifier) + "$C";

    // set up a new coefficient
    entry.id(ID_symbol);
    entry.set(ID_identifier, ident);

    // adjust the coefficient type
    entry.type()=signedbv_typet(2); //expr.type();
  }

  return entry;
}
Example #19
0
const exprt qbf_squolem_coret::f_get_cnf(WitnessStack *wsp)
{
  Clause *p=wsp->negWits;

  if(!p) return exprt(ID_true, typet(ID_bool));

  exprt::operandst operands;

  while(p!=NULL)
  {
    exprt clause=or_exprt();

    for(unsigned i=0; i<p->size; i++)
    {
      const Literal &lit=p->literals[i];
      exprt subf = f_get(literalt(var(lit), isPositive(lit))); // negated!
      if(find(clause.operands().begin(), clause.operands().end(), subf)==
         clause.operands().end())
        clause.move_to_operands(subf);
    }

    if(clause.operands().empty())
      clause=false_exprt();
    else if(clause.operands().size()==1)
    {
      const exprt tmp=clause.op0();
      clause=tmp;
    }

    #if 0
    std::cout << "CLAUSE: " << clause << std::endl;
    #endif

    operands.push_back(clause);

    p=p->next;
  }

  return and_exprt(operands);
}
Example #20
0
exprt gen_one(const typet &type)
{
  const std::string &type_id=type.id_string();
  exprt result=exprt("constant", type);

  if(type_id=="bool" ||
     type_id=="rational" ||
     type_id=="real" ||
     type_id=="integer" ||
     type_id=="natural" ||
     type_id=="complex")
  {
    result.value("1");
  }
  else if(type_id=="unsignedbv" ||
          type_id=="signedbv")
  {
    std::string value;
    for(int i=0; i<atoi(type.width().c_str())-1; i++)
      value+='0';
    value+='1';
    result.value(value);
  }
  else if(type_id=="fixedbv")
  {
    fixedbvt fixedbv;
    fixedbv.spec=to_fixedbv_type(type);
    fixedbv.from_integer(1);
    result=fixedbv.to_expr();
  }
  else if(type_id=="floatbv")
  {
    std::cerr << "floatbv unsupported, sorry" << std::endl;
    abort();
  }
  else
    result.make_nil();

  return result;
}
Example #21
0
void make_it_a_predicate(
  const predicatest &predicates,
  exprt &expr,
  const namespacet &ns)
{
  bool negation;
  canonicalize(expr, negation, ns);

  // see if we have it
  unsigned nr;
  if(predicates.find(expr, nr))
  {
    // yes, we do!

    // see if it is a constant
    if(predicates[nr].is_true())
      expr.make_true();
    else if(predicates[nr].is_false())
      expr.make_false();
    else
    {
      expr=exprt(ID_predicate_symbol, typet(ID_bool));
      expr.set(ID_identifier, nr);
    }

    if(negation)
      expr.make_not();
  }
  else
  {
    // nah, we don't
    // make it nondeterministic choice
    exprt tmp(ID_nondet_symbol, typet(ID_bool));
    tmp.add(ID_expression).swap(expr);
    expr.swap(tmp);
  }
}
Example #22
0
void ansi_c_convert_typet::read_rec(const typet &type)
{
  if(type.id()==ID_merged_type)
  {
    forall_subtypes(it, type)
      read_rec(*it);
  }
  else if(type.id()==ID_signed)
    signed_cnt++;
  else if(type.id()==ID_unsigned)
    unsigned_cnt++;
  else if(type.id()==ID_ptr32)
    c_qualifiers.is_ptr32=true;
  else if(type.id()==ID_ptr64)
    c_qualifiers.is_ptr64=true;
  else if(type.id()==ID_volatile)
    c_qualifiers.is_volatile=true;
  else if(type.id()==ID_asm)
  {
    // These are called 'asm labels' by GCC.
    // ignore for now
  }
  else if(type.id()==ID_const)
    c_qualifiers.is_constant=true;
  else if(type.id()==ID_restrict)
    c_qualifiers.is_restricted=true;
  else if(type.id()==ID_atomic)
    c_qualifiers.is_atomic=true;
  else if(type.id()==ID_atomic_type_specifier)
  {
    // this gets turned into the qualifier, uh
    c_qualifiers.is_atomic=true;
    read_rec(type.subtype());
  }
  else if(type.id()==ID_char)
    char_cnt++;
  else if(type.id()==ID_int)
    int_cnt++;
  else if(type.id()==ID_int8)
    int8_cnt++;
  else if(type.id()==ID_int16)
    int16_cnt++;
  else if(type.id()==ID_int32)
    int32_cnt++;
  else if(type.id()==ID_int64)
    int64_cnt++;
  else if(type.id()==ID_gcc_float128)
    gcc_float128_cnt++;
  else if(type.id()==ID_gcc_int128)
    gcc_int128_cnt++;
  else if(type.id()==ID_gcc_attribute_mode)
  {
    gcc_attribute_mode=type;
  }
  else if(type.id()==ID_gcc_attribute)
  {
  }
  else if(type.id()==ID_msc_based)
  {
    const exprt &as_expr=static_cast<const exprt &>(static_cast<const irept &>(type));
    assert(as_expr.operands().size()==1);
    msc_based=as_expr.op0();
  }
  else if(type.id()==ID_custom_bv)
  {
    bv_cnt++;
    const exprt &size_expr=
      static_cast<const exprt &>(type.find(ID_size));
      
    bv_width=size_expr;
  }
  else if(type.id()==ID_custom_floatbv)
  {
    floatbv_cnt++;

    const exprt &size_expr=
      static_cast<const exprt &>(type.find(ID_size));
    const exprt &fsize_expr=
      static_cast<const exprt &>(type.find(ID_f));

    bv_width=size_expr;
    fraction_width=fsize_expr;
  }
  else if(type.id()==ID_custom_fixedbv)
  {
    fixedbv_cnt++;

    const exprt &size_expr=
      static_cast<const exprt &>(type.find(ID_size));
    const exprt &fsize_expr=
      static_cast<const exprt &>(type.find(ID_f));

    bv_width=size_expr;
    fraction_width=fsize_expr;
  }
  else if(type.id()==ID_short)
    short_cnt++;
  else if(type.id()==ID_long)
    long_cnt++;
  else if(type.id()==ID_double)
    double_cnt++;
  else if(type.id()==ID_float)
    float_cnt++;
  else if(type.id()==ID_c_bool)
    c_bool_cnt++;
  else if(type.id()==ID_proper_bool)
    proper_bool_cnt++;
  else if(type.id()==ID_complex)
    complex_cnt++;
  else if(type.id()==ID_static)
    c_storage_spec.is_static=true;
  else if(type.id()==ID_thread_local)
    c_storage_spec.is_thread_local=true;
  else if(type.id()==ID_inline)
    c_storage_spec.is_inline=true;
  else if(type.id()==ID_extern)
    c_storage_spec.is_extern=true;
  else if(type.id()==ID_typedef)
    c_storage_spec.is_typedef=true;
  else if(type.id()==ID_register)
    c_storage_spec.is_register=true;
  else if(type.id()==ID_auto)
  {
    // ignore
  }
  else if(type.id()==ID_packed)
    packed=true;
  else if(type.id()==ID_aligned)
  {
    aligned=true;

    // may come with size or not
    if(type.find(ID_size).is_nil())
      alignment=exprt(ID_default);
    else
      alignment=static_cast<const exprt &>(type.find(ID_size));
  }
  else if(type.id()==ID_transparent_union)
  {
    c_qualifiers.is_transparent_union=true;
  }
  else if(type.id()==ID_vector)
    vector_size=to_vector_type(type).size();
  else if(type.id()==ID_void)
  {
    // we store 'void' as 'empty'
    typet tmp=type;
    tmp.id(ID_empty);
    other.push_back(tmp);
  }
  else if(type.id()==ID_msc_declspec)
  {
    const exprt &as_expr=
      static_cast<const exprt &>(static_cast<const irept &>(type));
      
    forall_operands(it, as_expr)
    {
      // these are symbols
      const irep_idt &id=it->get(ID_identifier);

      if(id=="thread")
        c_storage_spec.is_thread_local=true;
      else if(id=="align")
      {
        assert(it->operands().size()==1);
        aligned=true;
        alignment=it->op0();
      }
    }
  }
  else
exprt c_typecheck_baset::do_initializer_list(
  const exprt &value,
  const typet &type,
  bool force_constant)
{
  assert(value.id()==ID_initializer_list);

  const typet &full_type=follow(type);

  exprt result;
  if(full_type.id()==ID_struct ||
     full_type.id()==ID_union ||
     full_type.id()==ID_vector)
  {
    // start with zero everywhere
    result=
      zero_initializer(
        type, value.source_location(), *this, get_message_handler());
  }
  else if(full_type.id()==ID_array)
  {
    if(to_array_type(full_type).size().is_nil())
    {
      // start with empty array
      result=exprt(ID_array, full_type);
      result.add_source_location()=value.source_location();
    }
    else
    {
      // start with zero everywhere
      result=
        zero_initializer(
          type, value.source_location(), *this, get_message_handler());
    }

    // 6.7.9, 14: An array of character type may be initialized by a character
    // string literal or UTF-8 string literal, optionally enclosed in braces.
    if(value.operands().size()>=1 &&
       value.op0().id()==ID_string_constant &&
       (full_type.subtype().id()==ID_signedbv ||
        full_type.subtype().id()==ID_unsignedbv) &&
       full_type.subtype().get(ID_width)==char_type().get(ID_width))
    {
      if(value.operands().size()>1)
      {
        warning().source_location=value.find_source_location();
        warning() << "ignoring excess initializers" << eom;
      }

      return do_initializer_rec(value.op0(), type, force_constant);
    }
  }
  else
  {
    // The initializer for a scalar shall be a single expression,
    // * optionally enclosed in braces. *

    if(value.operands().size()==1)
      return do_initializer_rec(value.op0(), type, force_constant);

    err_location(value);
    error() << "cannot initialize `" << to_string(full_type)
            << "' with an initializer list" << eom;
    throw 0;
  }

  designatort current_designator;

  designator_enter(type, current_designator);

  forall_operands(it, value)
  {
    do_designated_initializer(
      result, current_designator, *it, force_constant);

    // increase designator -- might go up
    increment_designator(current_designator);
  }
Example #24
0
void goto_symext::symex_decl(statet &state)
{
  const goto_programt::instructiont &instruction=*state.source.pc;

  const codet &code=to_code(instruction.code);

  if(code.operands().size()==2)
    throw "two-operand decl not supported here";

  if(code.operands().size()!=1)
    throw "decl expects one operand";
  
  if(code.op0().id()!=ID_symbol)
    throw "decl expects symbol as first operand";

  // We increase the L2 renaming to make these non-deterministic.
  // We also prevent propagation of old values.
  
  const irep_idt &identifier=
    to_symbol_expr(code.op0()).get_identifier();
    
  const irep_idt l1_identifier=
    state.rename(identifier, ns, goto_symex_statet::L1);
    
  // prevent propagation
  state.propagation.remove(l1_identifier);

  // L2 renaming
  unsigned new_count=state.level2.current_count(l1_identifier)+1;
  state.level2.rename(l1_identifier, new_count);
    
  // in case of pointers, put something into the value set
  if(ns.follow(code.op0().type()).id()==ID_pointer)
  {
    exprt failed=
      get_failed_symbol(to_symbol_expr(code.op0()), ns);
    
    exprt rhs;
    
    if(failed.is_not_nil())
    {
      address_of_exprt address_of_expr;
      address_of_expr.object()=failed;
      address_of_expr.type()=code.op0().type();
      rhs=address_of_expr;
    }
    else
      rhs=exprt(ID_invalid);
    
    symbol_exprt l1_lhs;
    l1_lhs.type()=code.op0().type();
    l1_lhs.set_identifier(l1_identifier);
    state.rename(rhs, ns, goto_symex_statet::L1);
    state.value_set.assign(l1_lhs, rhs, ns);
  }
  
  // record the declaration
  symbol_exprt original_lhs=to_symbol_expr(code.op0());
  symbol_exprt ssa_lhs=original_lhs;
  state.rename(ssa_lhs, ns);
  
  target.decl(
    state.guard,
    ssa_lhs, original_lhs,
    state.source);
}
Example #25
0
void value_sett::get_value_set_rec(
  const exprt &expr,
  object_mapt &dest,
  const std::string &suffix,
  const typet &original_type,
  const namespacet &ns) const
{
  #if 0
  std::cout << "GET_VALUE_SET_REC EXPR: " << from_expr(ns, "", expr) << "\n";
  std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << std::endl;
  #endif

  const typet &expr_type=ns.follow(expr.type());

  if(expr.id()==ID_unknown || expr.id()==ID_invalid)
  {
    insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);

    const typet &type=ns.follow(expr.op0().type());

    assert(type.id()==ID_array ||
           type.id()==ID_incomplete_array);

    get_value_set_rec(expr.op0(), dest, "[]"+suffix, original_type, ns);
  }
  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 ||
           type.id()==ID_incomplete_struct ||
           type.id()==ID_incomplete_union);

    const std::string &component_name=
      expr.get_string(ID_component_name);

    get_value_set_rec(expr.op0(), dest,
      "."+component_name+suffix, original_type, ns);
  }
  else if(expr.id()==ID_symbol)
  {
    irep_idt identifier=to_symbol_expr(expr).get_identifier();

    // is it a pointer, integer, array or struct?
    if(expr_type.id()==ID_pointer ||
       expr_type.id()==ID_signedbv ||
       expr_type.id()==ID_unsignedbv ||
       expr_type.id()==ID_struct ||
       expr_type.id()==ID_union ||
       expr_type.id()==ID_array)
    {
      // look it up
      valuest::const_iterator v_it=
        values.find(id2string(identifier)+suffix);

      // try first component name as suffix if not yet found
      if(v_it==values.end() &&
          (expr_type.id()==ID_struct ||
           expr_type.id()==ID_union))
      {
        const struct_union_typet &struct_union_type=
          to_struct_union_type(expr_type);

        const std::string first_component_name=
          struct_union_type.components().front().get_string(ID_name);

        v_it=values.find(
            id2string(identifier)+"."+first_component_name+suffix);
      }

      // not found? try without suffix
      if(v_it==values.end())
        v_it=values.find(identifier);

      if(v_it!=values.end())
        make_union(dest, v_it->second.object_map);
      else
        insert(dest, exprt(ID_unknown, original_type));
    }
    else
      insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_if)
  {
    if(expr.operands().size()!=3)
      throw "if takes three operands";

    get_value_set_rec(expr.op1(), dest, suffix, original_type, ns);
    get_value_set_rec(expr.op2(), dest, suffix, original_type, ns);
  }
  else if(expr.id()==ID_address_of)
  {
    if(expr.operands().size()!=1)
      throw expr.id_string()+" expected to have one operand";

    get_reference_set(expr.op0(), dest, ns);
  }
  else if(expr.id()==ID_dereference)
  {
    object_mapt reference_set;
    get_reference_set(expr, reference_set, ns);
    const object_map_dt &object_map=reference_set.read();

    if(object_map.begin()==object_map.end())
      insert(dest, exprt(ID_unknown, original_type));
    else
    {
      for(object_map_dt::const_iterator
          it1=object_map.begin();
          it1!=object_map.end();
          it1++)
      {
        const exprt &object=object_numbering[it1->first];
        get_value_set_rec(object, dest, suffix, original_type, ns);
      }
    }
  }
  else if(expr.id()=="reference_to")
  {
    // old stuff, will go away
    object_mapt reference_set;

    get_reference_set(expr, reference_set, ns);

    const object_map_dt &object_map=reference_set.read();

    if(object_map.begin()==object_map.end())
      insert(dest, exprt(ID_unknown, original_type));
    else
    {
      for(object_map_dt::const_iterator
          it=object_map.begin();
          it!=object_map.end();
          it++)
      {
        const exprt &object=object_numbering[it->first];
        get_value_set_rec(object, dest, suffix, original_type, ns);
      }
    }
  }
  else if(expr.is_constant())
  {
    // check if NULL
    if(expr.get(ID_value)==ID_NULL &&
       expr_type.id()==ID_pointer)
    {
      insert(dest, exprt("NULL-object", expr_type.subtype()), 0);
    }
    else if(expr_type.id()==ID_unsignedbv ||
            expr_type.id()==ID_signedbv)
    {
      // an integer constant got turned into a pointer
      insert(dest, exprt(ID_integer_address, unsigned_char_type()));
    }
    else
      insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_typecast)
  {
    if(expr.operands().size()!=1)
      throw "typecast takes one operand";

    // let's see what gets converted to what

    const typet &op_type=ns.follow(expr.op0().type());

    if(op_type.id()==ID_pointer)
    {
      // pointer-to-pointer -- we just ignore these
      get_value_set_rec(expr.op0(), dest, suffix, original_type, ns);
    }
    else if(op_type.id()==ID_unsignedbv ||
            op_type.id()==ID_signedbv)
    {
      // integer-to-pointer

      if(expr.op0().is_zero())
        insert(dest, exprt("NULL-object", expr_type.subtype()), 0);
      else
      {
        // see if we have something for the integer
        object_mapt tmp;

        get_value_set_rec(expr.op0(), tmp, suffix, original_type, ns);

        if(tmp.read().size()==0)
        {
          // if not, throw in integer
          insert(dest, exprt(ID_integer_address, unsigned_char_type()));
        }
        else if(tmp.read().size()==1 &&
                object_numbering[tmp.read().begin()->first].id()==ID_unknown)
        {
          // if not, throw in integer
          insert(dest, exprt(ID_integer_address, unsigned_char_type()));
        }
        else
        {
          // use as is
          dest.write().insert(tmp.read().begin(), tmp.read().end());
        }
      }
    }
    else
      insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_plus ||
          expr.id()==ID_minus)
  {
    if(expr.operands().size()<2)
      throw expr.id_string()+" expected to have at least two operands";

    object_mapt pointer_expr_set;
    mp_integer i;
    bool i_is_set=false;

    // special case for pointer+integer

    if(expr.operands().size()==2 &&
       expr_type.id()==ID_pointer)
    {
      exprt ptr_operand;

      if(expr.op0().type().id()!=ID_pointer &&
         expr.op0().is_constant())
      {
        i_is_set=!to_integer(expr.op0(), i);
        ptr_operand=expr.op1();
      }
      else
      {
        i_is_set=!to_integer(expr.op1(), i);
        ptr_operand=expr.op0();
      }

      if(i_is_set)
      {
        i*=pointer_offset_size(ptr_operand.type().subtype(), ns);

        if(expr.id()==ID_minus) i.negate();
      }

      get_value_set_rec(
        ptr_operand, pointer_expr_set, "", ptr_operand.type(), ns);
    }
    else
    {
      // we get the points-to for all operands, even integers
      forall_operands(it, expr)
      {
        get_value_set_rec(
          *it, pointer_expr_set, "", it->type(), ns);
      }
    }

    for(object_map_dt::const_iterator
        it=pointer_expr_set.read().begin();
        it!=pointer_expr_set.read().end();
        it++)
    {
      objectt object=it->second;

      // adjust by offset
      if(object.offset_is_zero() && i_is_set)
        object.offset=i;
      else
        object.offset_is_set=false;

      insert(dest, it->first, object);
    }
  }
Example #26
0
exprt boolbvt::bv_get_rec(
    const bvt &bv,
    const std::vector<bool> &unknown,
    std::size_t offset,
    const typet &type) const
{
    if(type.id()==ID_symbol)
        return bv_get_rec(bv, unknown, offset, ns.follow(type));

    std::size_t width=boolbv_width(type);

    assert(bv.size()==unknown.size());
    assert(bv.size()>=offset+width);

    if(type.id()==ID_bool)
    {
        if(!unknown[offset])
        {
            switch(prop.l_get(bv[offset]).get_value())
            {
            case tvt::tv_enumt::TV_FALSE:
                return false_exprt();
            case tvt::tv_enumt::TV_TRUE:
                return true_exprt();
            default:
                return false_exprt(); // default
            }
        }

        return nil_exprt();
    }

    bvtypet bvtype=get_bvtype(type);

    if(bvtype==IS_UNKNOWN)
    {
        if(type.id()==ID_array)
        {
            const typet &subtype=type.subtype();
            std::size_t sub_width=boolbv_width(subtype);

            if(sub_width!=0)
            {
                exprt::operandst op;
                op.reserve(width/sub_width);

                for(std::size_t new_offset=0;
                        new_offset<width;
                        new_offset+=sub_width)
                {
                    op.push_back(
                        bv_get_rec(bv, unknown, offset+new_offset, subtype));
                }

                exprt dest=exprt(ID_array, type);
                dest.operands().swap(op);
                return dest;
            }
        }
        else if(type.id()==ID_struct_tag)
        {
            return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_struct_tag_type(type)));
        }
        else if(type.id()==ID_union_tag)
        {
            return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_union_tag_type(type)));
        }
        else if(type.id()==ID_struct)
        {
            const struct_typet &struct_type=to_struct_type(type);
            const struct_typet::componentst &components=struct_type.components();
            std::size_t new_offset=0;
            exprt::operandst op;
            op.reserve(components.size());

            for(struct_typet::componentst::const_iterator
                    it=components.begin();
                    it!=components.end();
                    it++)
            {
                const typet &subtype=ns.follow(it->type());
                op.push_back(nil_exprt());

                std::size_t sub_width=boolbv_width(subtype);

                if(sub_width!=0)
                {
                    op.back()=bv_get_rec(bv, unknown, offset+new_offset, subtype);
                    new_offset+=sub_width;
                }
            }

            struct_exprt dest(type);
            dest.operands().swap(op);
            return dest;
        }
        else if(type.id()==ID_union)
        {
            const union_typet &union_type=to_union_type(type);
            const union_typet::componentst &components=union_type.components();

            assert(!components.empty());

            // Any idea that's better than just returning the first component?
            std::size_t component_nr=0;

            union_exprt value(union_type);

            value.set_component_name(
                components[component_nr].get_name());

            const typet &subtype=components[component_nr].type();

            value.op()=bv_get_rec(bv, unknown, offset, subtype);

            return value;
        }
        else if(type.id()==ID_vector)
        {
            const typet &subtype=ns.follow(type.subtype());
            std::size_t sub_width=boolbv_width(subtype);

            if(sub_width!=0 && width%sub_width==0)
            {
                std::size_t size=width/sub_width;
                exprt value(ID_vector, type);
                value.operands().resize(size);

                for(std::size_t i=0; i<size; i++)
                    value.operands()[i]=
                        bv_get_rec(bv, unknown, i*sub_width, subtype);

                return value;
            }
        }
        else if(type.id()==ID_complex)
        {
            const typet &subtype=ns.follow(type.subtype());
            std::size_t sub_width=boolbv_width(subtype);

            if(sub_width!=0 && width==sub_width*2)
            {
                exprt value(ID_complex, type);
                value.operands().resize(2);

                value.op0()=bv_get_rec(bv, unknown, 0*sub_width, subtype);
                value.op1()=bv_get_rec(bv, unknown, 1*sub_width, subtype);

                return value;
            }
        }
    }

    std::string value;

    for(std::size_t bit_nr=offset; bit_nr<offset+width; bit_nr++)
    {
        char ch;
        if(unknown[bit_nr])
            ch='0';
        else
            switch(prop.l_get(bv[bit_nr]).get_value())
            {
            case tvt::tv_enumt::TV_FALSE:
                ch='0';
                break;
            case tvt::tv_enumt::TV_TRUE:
                ch='1';
                break;
            case tvt::tv_enumt::TV_UNKNOWN:
                ch='0';
                break;
            default:
                assert(false);
            }

        value=ch+value;
    }

    switch(bvtype)
    {
    case IS_UNKNOWN:
        if(type.id()==ID_string)
        {
            mp_integer int_value=binary2integer(value, false);
            irep_idt s;
            if(int_value>=string_numbering.size())
                s=irep_idt();
            else
                s=string_numbering[int_value.to_long()];

            return constant_exprt(s, type);
        }
        break;

    case IS_RANGE:
    {
        mp_integer int_value=binary2integer(value, false);
        mp_integer from=string2integer(type.get_string(ID_from));

        constant_exprt value_expr(type);
        value_expr.set_value(integer2string(int_value+from));
        return value_expr;
    }
    break;

    default:
    case IS_C_ENUM:
        constant_exprt value_expr(type);
        value_expr.set_value(value);
        return value_expr;
    }

    return nil_exprt();
}
Example #27
0
exprt boolbvt::bv_get_unbounded_array(const exprt &expr) const
{
    // first, try to get size

    const typet &type=expr.type();
    const exprt &size_expr=to_array_type(type).size();
    exprt size=simplify_expr(get(size_expr), ns);

    // no size, give up
    if(size.is_nil()) return nil_exprt();

    // get the numeric value, unless it's infinity
    mp_integer size_mpint;

    if(size.id()!=ID_infinity)
    {
        if(to_integer(size, size_mpint))
            return nil_exprt();

        // simple sanity check
        if(size_mpint<0)
            return nil_exprt();
    }
    else
        size_mpint=0;

    // search array indices

    typedef std::map<mp_integer, exprt> valuest;
    valuest values;

    {
        std::size_t number;

        if(arrays.get_number(expr, number))
            return nil_exprt();

        // get root
        number=arrays.find_number(number);

        assert(number<index_map.size());
        index_mapt::const_iterator it=index_map.find(number);
        assert(it!=index_map.end());
        const index_sett &index_set=it->second;

        for(index_sett::const_iterator it1=
                    index_set.begin();
                it1!=index_set.end();
                it1++)
        {
            index_exprt index;
            index.type()=type.subtype();
            index.array()=expr;
            index.index()=*it1;

            exprt value=bv_get_cache(index);
            exprt index_value=bv_get_cache(*it1);

            if(!index_value.is_nil())
            {
                mp_integer index_mpint;

                if(!to_integer(index_value, index_mpint))
                {
                    if(value.is_nil())
                        values[index_mpint]=exprt(ID_unknown, type.subtype());
                    else
                        values[index_mpint]=value;
                }
            }
        }
    }

    exprt result;

    if(size_mpint>100 || size.id()==ID_infinity)
    {
        result=exprt("array-list", type);
        result.type().set(ID_size, integer2string(size_mpint));

        result.operands().reserve(values.size()*2);

        for(valuest::const_iterator it=values.begin();
                it!=values.end();
                it++)
        {
            exprt index=from_integer(it->first, size.type());
            result.copy_to_operands(index, it->second);
        }
    }
    else
    {
        // set the size
        result=exprt(ID_array, type);
        result.type().set(ID_size, size);

        std::size_t size_int=integer2size_t(size_mpint);

        // allocate operands
        result.operands().resize(size_int);

        for(std::size_t i=0; i<size_int; i++)
            result.operands()[i]=exprt(ID_unknown);

        // search uninterpreted functions

        for(valuest::iterator it=values.begin();
                it!=values.end();
                it++)
            if(it->first>=0 && it->first<size_mpint)
                result.operands()[integer2size_t(it->first)].swap(it->second);
    }

    return result;
}
Example #28
0
exprt convert_float_literal(const std::string &src)
{
  mp_integer significand;
  mp_integer exponent;
  bool is_float, is_long, is_imaginary;
  bool is_decimal, is_float80, is_float128; // GCC extensions
  unsigned base;
  
  parse_float(src, significand, exponent, base,
              is_float, is_long, is_imaginary,
              is_decimal, is_float80, is_float128);

  exprt result=exprt(ID_constant);
  
  result.set(ID_C_cformat, src);
  
  // In ANSI-C, float literals are double by default,
  // unless marked with 'f'.
  // All of these can be complex as well.
  // This can be overriden with
  // config.ansi_c.single_precision_constant.

  if(is_float)
    result.type()=float_type();
  else if(is_long)
    result.type()=long_double_type();
  else if(is_float80)
  {
    result.type()=ieee_float_spect(64, 15).to_type();
    result.type().set(ID_C_c_type, ID_long_double);
  }
  else if(is_float128)
  {
    result.type()=ieee_float_spect::quadruple_precision().to_type();
    result.type().set(ID_C_c_type, ID_gcc_float128);
  }
  else
  {
    // default
    if(config.ansi_c.single_precision_constant)
      result.type()=float_type(); // default
    else
      result.type()=double_type(); // default
  }

  if(is_decimal)
  {
    // TODO - should set ID_gcc_decimal32/ID_gcc_decimal64/ID_gcc_decimal128,
    // but these aren't handled anywhere
  }
  
  if(config.ansi_c.use_fixed_for_float)
  {
    unsigned width=result.type().get_int(ID_width);
    unsigned fraction_bits;
    const irep_idt integer_bits=result.type().get(ID_integer_bits);
    
    assert(width!=0);

    if(integer_bits==irep_idt())
      fraction_bits=width/2; // default
    else
      fraction_bits=width-safe_string2int(id2string(integer_bits));

    mp_integer factor=mp_integer(1)<<fraction_bits;
    mp_integer value=significand*factor;
    
    if(value!=0)
    {
      if(exponent<0)
        value/=power(base, -exponent);
      else
      {
        value*=power(base, exponent);    

        if(value>=power(2, width-1))
        {
          // saturate: use "biggest value"
          value=power(2, width-1)-1;
        }
        else if(value<=-power(2, width-1)-1)
        {
          // saturate: use "smallest value"
          value=-power(2, width-1);
        }
      }
    }

    result.set(ID_value, integer2binary(value, width));  
  }
  else
  {
    ieee_floatt a;

    a.spec=to_floatbv_type(result.type());
    
    if(base==10)
      a.from_base10(significand, exponent);
    else if(base==2) // hex
      a.build(significand, exponent);
    else
      assert(false);

    result.set(ID_value,
      integer2binary(a.pack(), a.spec.width()));  
  }

  if(is_imaginary)
  {
    complex_typet complex_type;
    complex_type.subtype()=result.type();
    exprt complex_expr(ID_complex, complex_type);
    complex_expr.operands().resize(2);
    complex_expr.op0()=gen_zero(result.type());
    complex_expr.op1()=result;
    return complex_expr;
  }
  
  return result;
}
Example #29
0
void jsil_typecheckt::typecheck_function_call(
  code_function_callt &call)
{
  if(call.operands().size()!=3)
    throw "function call expected to have three operands";

  exprt &lhs=call.lhs();
  typecheck_expr(lhs);

  exprt &f=call.function();
  typecheck_expr(f);

  for(auto &arg : call.arguments())
    typecheck_expr(arg);

  // Look for a function declaration symbol in the symbol table
  if(f.id()==ID_symbol)
  {
    const irep_idt &id=to_symbol_expr(f).get_identifier();

    if(symbol_table.has_symbol(id))
    {
      symbolt &s=symbol_table.lookup(id);

      if(s.type.id()==ID_code)
      {
        code_typet &codet=to_code_type(s.type);

        for(std::size_t i=0; i<codet.parameters().size(); i++)
        {
          if(i>=call.arguments().size()) break;

          const typet &param_type=codet.parameters()[i].type();

          if(!param_type.id().empty() && param_type.is_not_nil())
          {
             // check argument's type if parameter's type is given
             make_type_compatible(call.arguments()[i], param_type, true);
          }
        }

        // if there are too few arguments, add undefined
        if(codet.parameters().size()>call.arguments().size())
        {
          for(std::size_t i=call.arguments().size();
              i<codet.parameters().size();
              ++i)
            call.arguments().push_back(
              exprt("undefined", jsil_undefined_type()));
        }

        // if there are too many arguments, remove
        while(codet.parameters().size()<call.arguments().size())
          call.arguments().pop_back();

        // check return type if exists
        if(!codet.return_type().id().empty() &&
            codet.return_type().is_not_nil())
          make_type_compatible(lhs, codet.return_type(), true);
        else make_type_compatible(lhs, jsil_any_type(), true);
      }
      else
      {
        // TODO: a symbol can be a variable evaluating to a string
        // which corresponds to a function identifier
        make_type_compatible(lhs, jsil_any_type(), true);
      }
    }
    else
    {
      // Should be function, declaration not found yet
      symbolt new_symbol;
      new_symbol.name=id;
      new_symbol.type=code_typet();
      new_symbol.mode="jsil";
      new_symbol.is_type=false;
      new_symbol.value=exprt("no-body-just-yet");

      make_type_compatible(lhs, jsil_any_type(), true);

      if(symbol_table.add(new_symbol))
        throw "failed to add expression symbol to symbol table";
    }
  }
  else
  {
    // TODO: this might be a string literal
    // which corresponds to a function identifier
    make_type_compatible(lhs, jsil_any_type(), true);
  }
}
Example #30
0
void predicate_image_satqe(
    message_handlert &message_handler,
    const std::vector<exprt> &deref_curr_predicates,
    const std::vector<exprt> &deref_next_predicates,
    const std::list<exprt> &constraints,
    symex_target_equationt &equation,
    const namespacet &ns,
    abstract_transition_relationt &
    abstract_transition_relation)
{
  const std::set<unsigned> &from_predicates=
    abstract_transition_relation.from_predicates;

  const std::set<unsigned> &to_predicates=
    abstract_transition_relation.to_predicates;

  assert(to_predicates.size()!=0);

  // create SAT solver object
  satqe_satcheckt satqe;
  bv_pointerst solver(satqe);

  solver.unbounded_array=boolbvt::U_ALL;
  solver.set_message_handler(message_handler);

  // turn equation into CNF
  equation.convert(solver);

  for(std::set<unsigned>::const_iterator
      it=from_predicates.begin();
      it!=from_predicates.end();
      it++)
  {
    unsigned i=*it;

    literalt li=make_pos(ns, solver, deref_curr_predicates[i]);
    satqe.quantify(li);
  }

  for(std::set<unsigned>::const_iterator
      it=to_predicates.begin();
      it!=to_predicates.end();
      it++)
  {
    unsigned i=*it;

    literalt lo=make_pos(ns, solver, deref_next_predicates[i]);
    satqe.quantify(lo);
  }

  // we want cubes
  cube_sett cube_set;
  satqe.set_cube_set(cube_set);

  // solve it
  switch(solver.dec_solve())
  {
    case decision_proceduret::D_UNSATISFIABLE:
      // OK, this is what we expect
      break;

    default:
      throw "unexpected result from satqe.solve()";
  }

  message_handler.print(9, "Generated "+
      i2string(cube_set.no_insertions())+" cube(s)");

#if 0
  std::cout << cube_set;
#endif

  exprt constraint_cubes_disj = true_exprt();

  // convert the cubes into constraints
  for(cubest::star_mapt::const_iterator
      it=cube_set.star_map.begin();
      it!=cube_set.star_map.end();
      it++)
  {
    for(cubest::bitssett::const_iterator
        it2=it->second.begin();
        it2!=it->second.end();
        it2++)
    {
      exprt constraint_cube_conj;

      unsigned bit=0;
      unsigned i=0;

      /* Assume it->first[i] is true iff the i-th predicate is in the
         cube. Assume predicates are stored in it->first in the order of
         from_predicates followed by to_predicates. Scan it->first and
         from/to_predicates in parallel to get the cube. */

      for(std::set<unsigned>::const_iterator
          it3=from_predicates.begin();
          it3!=from_predicates.end();
          it3++)
      {
        unsigned id=*it3;

        if(!it->first[i])
        {
          constraint_cube_conj.operands().push_back(exprt());
          exprt &e=constraint_cube_conj.operands().back();
          e=exprt(ID_predicate_symbol, typet(ID_bool));
          e.set(ID_identifier, id);

          if(!(*it2)[bit]) 
            e.make_not();

          bit++;
#if 0
          std::cout << "C: " << from_expr(ns, "", e) << std::endl;
#endif
        }

        i++;
      }

      for(std::set<unsigned>::const_iterator
          it3=to_predicates.begin();
          it3!=to_predicates.end();
          it3++)
      {
        unsigned id=*it3;

        if(!it->first[i])
        {
          constraint_cube_conj.operands().push_back(exprt());
          exprt &e=constraint_cube_conj.operands().back();
          e=exprt(ID_predicate_next_symbol, typet(ID_bool));
          e.set(ID_identifier, id);

          if(!(*it2)[bit]) 
            e.make_not();

          bit++;
#if 0
          std::cout << "C: " << from_expr(ns, "", e) << std::endl;
#endif
        }

        i++;
      }

      assert(i==it->first.size());

      /* Convert the cube into a conjunct. */
      gen_and(constraint_cube_conj);

      /* Add the conjunct in disjunction to previous cubes. */
      if(constraint_cubes_disj.is_true())
        constraint_cubes_disj=constraint_cube_conj;
      else
        constraint_cubes_disj=gen_or(
            constraint_cubes_disj,
            constraint_cube_conj);      
    }
  }

  /* Add the cubes to the contraints of the abstract transition
     relation. Warning: we may want to remove old constrains. */

  abstract_transition_relation.constraints.push_back(constraint_cubes_disj);
}