示例#1
0
bool inv_object_storet::is_constant_address(const exprt &expr)
{
  if(expr.id()==ID_address_of)
    if(expr.operands().size()==1)
      return is_constant_address_rec(expr.op0());

  return false;
}
示例#2
0
void bv_refinementt::convert_floatbv_op(const exprt &expr, bvt &bv)
{
  if(ns.follow(expr.type()).id()!=ID_floatbv ||
     expr.operands().size()!=3)
    return SUB::convert_floatbv_op(expr, bv);

  add_approximation(expr, bv);
}
示例#3
0
std::size_t pointer_logict::add_object(const exprt &expr)
{
  // remove any index/member

  if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);
    return add_object(expr.op0());
  }
  else if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);
    return add_object(expr.op0());
  }

  return objects.number(expr);
}
示例#4
0
bool simplify_exprt::simplify_ieee_float_relation(exprt &expr)
{
  assert(expr.id()==ID_ieee_float_equal ||
         expr.id()==ID_ieee_float_notequal);

  exprt::operandst &operands=expr.operands();

  if(expr.type().id()!=ID_bool)
    return true;

  if(operands.size()!=2)
    return true;

  // types must match
  if(expr.op0().type()!=expr.op1().type())
    return true;

  if(expr.op0().type().id()!=ID_floatbv)
    return true;

  // first see if we compare to a constant

  if(expr.op0().is_constant() &&
     expr.op1().is_constant())
  {
    ieee_floatt f0(to_constant_expr(expr.op0()));
    ieee_floatt f1(to_constant_expr(expr.op1()));

    if(expr.id()==ID_ieee_float_notequal)
      expr.make_bool(f0.ieee_not_equal(f1));
    else if(expr.id()==ID_ieee_float_equal)
      expr.make_bool(f0.ieee_equal(f1));
    else
      assert(false);

    return false;
  }

  if(expr.op0()==expr.op1())
  {
    // x!=x is the same as saying isnan(op)
    exprt isnan(ID_isnan, bool_typet());
    isnan.copy_to_operands(expr.op0());

    if(expr.id()==ID_ieee_float_notequal)
    {
    }
    else if(expr.id()==ID_ieee_float_equal)
      isnan.make_not();
    else
      assert(false);

    expr.swap(isnan);
    return false;
  }

  return true;
}
示例#5
0
bool inv_object_storet::is_constant_address_rec(const exprt &expr)
{
  if(expr.id()==ID_symbol)
    return true;
  else if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);
    return is_constant_address_rec(expr.op0());
  }
  else if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);
    if(expr.op1().is_constant())
      return is_constant_address_rec(expr.op0());
  }

  return false;
}
示例#6
0
void cvc_convt::convert_expr(const exprt &expr)
{
    const exprt::operandst &op=expr.operands();

    if(expr.id()==ID_implies)
    {
        if(op.size()!=2)
            throw "implication takes two operands";

        out << "(";
        convert_expr(op[0]);
        out << ") => (";
        convert_expr(op[1]);
        out << ")";
    }
    else if(expr.id()==ID_constraint_select_one)
    {
        if(op.size()<2)
            throw "constraint_select_one takes at least two operands";

        // TODO
        throw "cvc_convt::convert_expr needs constraint_select_one";
    }
    else if(expr.id()==ID_or || expr.id()==ID_and || expr.id()==ID_xor ||
            expr.id()==ID_nor || expr.id()==ID_nand)
    {
        if(op.empty())
            throw "operator `"+expr.id_string()+"' takes at least one operand";
        else if(op.size()==1)
            convert_expr(op[0]);
        else
        {
            forall_expr(it, op)
            {
                if(it!=op.begin())
                {
                    if(expr.id()==ID_or)
                        out << " OR ";
                    else if(expr.id()==ID_nor)
                        out << " NOR ";
                    else if(expr.id()==ID_and)
                        out << " AND ";
                    else if(expr.id()==ID_nand)
                        out << " NAND ";
                    else if(expr.id()==ID_xor)
                        out << " XOR ";
                    else
                        assert(false);
                }

                out << "(";
                convert_expr(*it);
                out << ")";
            }
        }
    }
    else if(expr.id()==ID_not)
示例#7
0
void boolbvt::convert_div(const exprt &expr, bvt &bv)
{
  if(expr.type().id()!=ID_unsignedbv &&
     expr.type().id()!=ID_signedbv &&
     expr.type().id()!=ID_fixedbv)
    return conversion_failed(expr, bv);

  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);

  if(expr.operands().size()!=2)
    throw "division takes two operands";

  if(expr.op0().type().id()!=expr.type().id() ||
     expr.op1().type().id()!=expr.type().id())
    return conversion_failed(expr, bv);

  bvt op0=convert_bv(expr.op0());
  bvt op1=convert_bv(expr.op1());

  if(op0.size()!=width ||
     op1.size()!=width)
    throw "convert_div: unexpected operand width";

  bvt res, rem;

  if(expr.type().id()==ID_fixedbv)
  {
    unsigned fraction_bits=
      to_fixedbv_type(expr.type()).get_fraction_bits();

    bvt zeros;
    zeros.resize(fraction_bits, const_literal(false));

    // add fraction_bits least-significant bits
    op0.insert(op0.begin(), zeros.begin(), zeros.end());
    op1=bv_utils.sign_extension(op1, op1.size()+fraction_bits);
  
    bv_utils.divider(op0, op1, res, rem, bv_utilst::SIGNED);
    
    // cut it down again
    res.resize(width);
  }
  else
  {
    bv_utilst::representationt rep=
      expr.type().id()==ID_signedbv?bv_utilst::SIGNED:
                                   bv_utilst::UNSIGNED;

    bv_utils.divider(op0, op1, res, rem, rep);
  }

  bv=res;
}
示例#8
0
void cnf_join_binary(exprt &expr)
{
  Forall_operands(it, expr)
    cnf_join_binary(*it);

  if(expr.id()==ID_and || expr.id()==ID_or || expr.id()==ID_xor ||
     expr.id()==ID_bitand || expr.id()==ID_bitor || expr.id()==ID_bitxor)
  {
    exprt tmp;

    if(expr.operands().size()==1)
    {
      tmp.swap(expr.op0());
      expr.swap(tmp);
    }
    else
    {
      unsigned count=0;

      forall_operands(it, expr)
      {
        if(it->id()==expr.id())
          count+=it->operands().size();
        else
          count++;
      }

      tmp.operands().reserve(count);

      Forall_operands(it, expr)
      {
        if(it->id()==expr.id())
        {
          Forall_operands(it2, *it)
            tmp.move_to_operands(*it2);
        }
        else
          tmp.move_to_operands(*it);
      }

      expr.operands().swap(tmp.operands());
    }
  }
示例#9
0
std::set<symbol_exprt> concurrency_aware_abstractort::targets_of_lvalue(const exprt& lvalue, goto_programt::const_targett program_location)
{

	std::set<symbol_exprt> result;
	if(lvalue.id() == ID_index)
	{
		exprt array_name = lvalue.op0();
		if(array_name.id() == ID_symbol)
		{
			result.insert(to_symbol_expr(array_name));
		} else {
			return targets_of_lvalue(array_name, program_location);
		}
	} else if(lvalue.id() == ID_member) {
		assert(lvalue.operands().size() == 1);
		return targets_of_lvalue(lvalue.op0(), program_location);
	} else if(lvalue.id() == ID_symbol) {
		result.insert(to_symbol_expr(lvalue));
	} else if(lvalue.id() == ID_dereference) {
		// We would like to add anything the pointer can point to,
		// but not the pointer itself

		value_setst::valuest value_set;
		pointer_info.get_values(program_location, lvalue.op0(), value_set);
		for(value_setst::valuest::iterator it = value_set.begin(); it != value_set.end(); it++)
		{
			if(it->id() != ID_object_descriptor)
			{
				// TODO: We may need to deal with this situation more carefully
				continue;
			}
			object_descriptor_exprt& object_descriptor = to_object_descriptor_expr(*it);
			if(object_descriptor.offset() != from_integer(0, index_type()))
			{
				std::cout << "Pointer " << from_expr(lvalue.op0()) << " can point to " << from_expr(*it) << " at line " <<
						program_location->location.get_line() << ", we cannot handle this" << std::endl;
				  exit(1);
			  }

			  if(object_descriptor.object().id() != ID_symbol)
			  {
				  std::cout << "Pointer " << from_expr(lvalue.op0()) << " can point to " << from_expr(*it) << " at line " <<
					  program_location->location.get_line() << ", we cannot handle this" << std::endl;
				  exit(1);
			  }

			  result.insert(to_symbol_expr(object_descriptor.object()));
		}

	} else {
		std::cout << "Cannot currently handle lvalue: " << from_expr(lvalue) << std::endl;
		assert(false);
	}
	return result;
}
示例#10
0
void invariant_sett::strengthen_rec(const exprt &expr)
{
  if(expr.type().id()!=ID_bool)
    throw "non-Boolean argument to strengthen()";

  #if 0
  std::cout << "S: " << from_expr(*ns, "", expr) << '\n';
  #endif

  if(is_false)
  {
    // we can't get any stronger
    return;
  }

  if(expr.is_true())
  {
    // do nothing, it's useless
  }
  else if(expr.is_false())
  {
    // wow, that's strong
    make_false();
  }
  else if(expr.id()==ID_not)
  {
    // give up, we expect NNF
  }
  else if(expr.id()==ID_and)
  {
    forall_operands(it, expr)
      strengthen_rec(*it);
  }
  else if(expr.id()==ID_le ||
          expr.id()==ID_lt)
  {
    assert(expr.operands().size()==2);

    // special rule: x <= (a & b)
    // implies:      x<=a && x<=b

    if(expr.op1().id()==ID_bitand)
    {
      const exprt &bitand_op=expr.op1();

      forall_operands(it, bitand_op)
      {
        exprt tmp(expr);
        tmp.op1()=*it;
        strengthen_rec(tmp);
      }

      return;
    }
示例#11
0
exprt dereferencet::dereference_rec(
  const exprt &address,
  const exprt &offset,
  const typet &type)
{
  if(address.id()==ID_address_of)
  {
    const address_of_exprt &address_of_expr=to_address_of_expr(address);

    const exprt &object=address_of_expr.object();

    return read_object(object, offset, type);
  }
  else if(address.id()==ID_typecast)
  {
    const typecast_exprt &typecast_expr=to_typecast_expr(address);

    return dereference_typecast(typecast_expr, offset, type);
  }
  else if(address.id()==ID_plus)
  {
    // pointer arithmetic
    if(address.operands().size()<2)
      throw "plus with less than two operands";

    return dereference_plus(address, offset, type);
  }
  else if(address.id()==ID_if)
  {
    const if_exprt &if_expr=to_if_expr(address);

    return dereference_if(if_expr, offset, type);
  }
  else if(address.id()==ID_constant)
  {
    const typet result_type=ns.follow(address.type()).subtype();

    // pointer-typed constant
    if(to_constant_expr(address).get_value()==ID_NULL) // NULL
    {
      // we turn this into (type *)0
      exprt zero=gen_zero(index_type());
      return dereference_rec(
        typecast_exprt(zero, address.type()), offset, type);
    }
    else
      throw "dereferencet: unexpected pointer constant "+address.pretty();
  }
  else
  {
    throw "failed to dereference `"+address.id_string()+"'";
  }
}
示例#12
0
void jsil_typecheckt::typecheck_expr_unary_num(exprt &expr)
{
  if(expr.operands().size()!=1)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects one operand" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), floatbv_typet(), true);
}
示例#13
0
void bv_refinementt::convert_mod(const exprt &expr, bvt &bv)
{
  // we catch any mod
  // unless it's integer + constant

  assert(expr.operands().size()==2);

  if(expr.op1().is_constant())
    return SUB::convert_mod(expr, bv);

  add_approximation(expr, bv);
}
示例#14
0
std::string expr2javat::convert_java_instanceof(
  const exprt &src,
  unsigned precedence)
{
  if(src.operands().size()!=2)
  {
    unsigned precedence;
    return convert_norep(src, precedence);
  }

  return convert(src.op0())+" instanceof "+convert(src.op1().type());
}
示例#15
0
void gen_binary(exprt &expr, const std::string &id, bool default_value)
{
  if(expr.operands().size()==0)
  {
    if(default_value)
      expr.make_true();
    else
      expr.make_false();
  }
  else if(expr.operands().size()==1)
  {
    exprt tmp;
    tmp.swap(expr.op0());
    expr.swap(tmp);
  }
  else
  {
    expr.id(id);
    expr.type()=typet("bool");
  }
}
示例#16
0
文件: value_set.cpp 项目: lihaol/cbmc
bool value_sett::eval_pointer_offset(
  exprt &expr,
  const namespacet &ns) const
{
  bool mod=false;

  if(expr.id()==ID_pointer_offset)
  {
    assert(expr.operands().size()==1);

    object_mapt reference_set;
    get_value_set(expr.op0(), reference_set, ns, true);

    exprt new_expr;
    mp_integer previous_offset=0;

    const object_map_dt &object_map=reference_set.read();
    for(object_map_dt::const_iterator
        it=object_map.begin();
        it!=object_map.end();
        it++)
      if(!it->second.offset_is_set)
        return false;
      else
      {
        const exprt &object=object_numbering[it->first];
        mp_integer ptr_offset=compute_pointer_offset(object, ns);

        if(ptr_offset<0)
          return false;

        ptr_offset+=it->second.offset;

        if(mod && ptr_offset!=previous_offset)
          return false;

        new_expr=from_integer(ptr_offset, index_type());
        previous_offset=ptr_offset;
        mod=true;
      }

    if(mod)
      expr.swap(new_expr);
  }
  else
  {
    Forall_operands(it, expr)
      mod=eval_pointer_offset(*it, ns) || mod;
  }

  return mod;
}
示例#17
0
literalt boolbvt::convert_quantifier(const exprt &expr)
{
  if(expr.operands().size()!=3)
    return SUB::convert_rest(expr);
  
  literalt l=prop.new_variable();
  
  quantifier_list.push_back(quantifiert());
  quantifier_list.back().l=l;
  quantifier_list.back().expr=expr;
  
  return l;
}
示例#18
0
文件: path_slicer.cpp 项目: olivo/BP
void path_slicert::get_symbols(const exprt &expr, string_sett &s)
{
    if(expr.id()==ID_symbol)
    {
        s.insert(to_symbol_expr(expr).get_identifier());
    }
    else if(expr.id()==ID_index)
    {
        assert(expr.operands().size()==2);
        string_sett tmp;
        get_symbols(expr.op0(), tmp);
        get_symbols(expr.op1(), s);

        for(string_sett::const_iterator
                it=tmp.begin();
                it!=tmp.end();
                it++)
            s.insert(id2string(*it)+"[]");
    }
    else if(expr.id()==ID_member)
    {
        assert(expr.operands().size()==1);

        string_sett tmp;

        get_symbols(expr.op0(), tmp);

        std::string suffix="."+expr.get_string(ID_component_name);

        for(string_sett::const_iterator
                it=tmp.begin();
                it!=tmp.end();
                it++)
            s.insert(id2string(*it)+suffix);
    }
    else
        forall_operands(it, expr)
        get_symbols(*it, s);
}
示例#19
0
bool simplify_exprt::simplify_isnormal(exprt &expr)
{
  if(expr.operands().size()!=1) return true;

  if(expr.op0().is_constant())
  {
    ieee_floatt value(to_constant_expr(expr.op0()));
    expr.make_bool(value.is_normal());
    return false;
  }

  return true;
}
示例#20
0
bvt bv_refinementt::convert_floatbv_op(const exprt &expr)
{
  if(!do_arithmetic_refinement)
    return SUB::convert_floatbv_op(expr);

  if(ns.follow(expr.type()).id()!=ID_floatbv ||
     expr.operands().size()!=3)
    return SUB::convert_floatbv_op(expr);

  bvt bv;
  add_approximation(expr, bv);
  return bv;
}
示例#21
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);
  }
示例#22
0
void preconditiont::compute_address_of(exprt &dest)
{
  if(dest.id()==ID_symbol)
  {
    // leave alone
  }
  else if(dest.id()==ID_index)
  {
    assert(dest.operands().size()==2);
    compute_address_of(dest.op0());
    compute(dest.op1());
  }
  else if(dest.id()==ID_member)
  {
    assert(dest.operands().size()==1);
    compute_address_of(dest.op0());
  }
  else if(dest.id()==ID_dereference)
  {
    assert(dest.operands().size()==1);
    compute(dest.op0());
  }
}
示例#23
0
static bool has_dereference(const exprt &expr)
{
  if (expr.id() == "dereference")
    return true;
  else if (expr.id() == "index" && expr.op0().type().id() == "pointer")
    // This is an index of a pointer, which is a dereference
    return true;
  else if (expr.operands().size() > 0 && expr.op0().is_not_nil())
    // Recurse through all subsequent source objects, which are always operand
    // zero.
    return has_dereference(expr.op0());
  else
    return false;
}
示例#24
0
void jsil_typecheckt::typecheck_exp_binary_equal(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

 // operands can be of any types

  expr.type()=bool_typet();
}
示例#25
0
void jsil_typecheckt::typecheck_expr_base(exprt &expr)
{
  if(expr.operands().size()!=1)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects single operand" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), jsil_reference_type(), true);

  expr.type()=jsil_value_type();
}
示例#26
0
exprt make_va_list(const exprt &expr)
{
  // we first strip any typecast
  if(expr.id()==ID_typecast)
    return make_va_list(to_typecast_expr(expr).op());

  // if it's an address of an lvalue, we take that
  if(expr.id()==ID_address_of &&
     expr.operands().size()==1 &&
     is_lvalue(expr.op0()))
    return expr.op0();

  return expr;
}
示例#27
0
void goto_checkt::overflow_check(const exprt &expr, const guardt &guard)
{
  if (!options.get_bool_option("overflow-check"))
    return;

  // first, check type
  if (expr.type().id() != "signedbv")
    return;

  // add overflow subgoal

  exprt overflow("overflow-" + expr.id_string(), bool_typet());
  overflow.operands() = expr.operands();

  if (expr.id() == "typecast")
  {
    if (expr.operands().size() != 1)
      throw "typecast takes one operand";

    const typet &old_type = expr.op0().type();

    unsigned new_width = atoi(expr.type().width().c_str());
    unsigned old_width = atoi(old_type.width().c_str());

    if (old_type.id() == "unsignedbv")
      new_width--;
    if (new_width >= old_width)
      return;

    overflow.id(overflow.id_string() + "-" + i2string(new_width));
  }

  overflow.make_not();

  add_guarded_claim(overflow, "arithmetic overflow on " + expr.id_string(),
      "overflow", expr.find_location(), guard);
}
示例#28
0
void jsil_typecheckt::typecheck_expr_proto_obj(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands";
    throw 0;
  }

  make_type_compatible(expr.op0(), jsil_object_type(), true);
  make_type_compatible(expr.op1(), jsil_object_type(), true);

  expr.type()=bool_typet();
}
示例#29
0
void jsil_typecheckt::typecheck_expr_binary_compare(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), floatbv_typet(), true);
  make_type_compatible(expr.op1(), floatbv_typet(), true);

  expr.type()=bool_typet();
}
示例#30
0
void jsil_typecheckt::typecheck_expr_concatenation(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), string_typet(), true);
  make_type_compatible(expr.op1(), string_typet(), true);

  expr.type()=string_typet();
}