예제 #1
0
void ansi_c_convertt::convert_expr(exprt &expr)
{
  if(expr.id()==ID_sideeffect)
  {
    const irep_idt &statement=expr.get(ID_statement);

    if(statement==ID_statement_expression)
    {
      assert(expr.operands().size()==1);
      convert_code(to_code(expr.op0()));
      return;
      // done
    }
  }

  Forall_operands(it, expr)
    convert_expr(*it);

  if(expr.id()==ID_symbol)
  {
    expr.remove(ID_C_id_class);
    expr.remove(ID_C_base_name);
  }
  else if(expr.id()==ID_sizeof)
  {
    if(expr.operands().size()==0)
    {
      typet &type=static_cast<typet &>(expr.add(ID_type_arg));
      convert_type(type);
    }
  }
  else if(expr.id()==ID_designated_initializer)
  {
    exprt &designator=static_cast<exprt &>(expr.add(ID_designator));
    convert_expr(designator);
  }
  else if(expr.id()==ID_alignof)
  {
    if(expr.operands().size()==0)
    {
      typet &type=static_cast<typet &>(expr.add(ID_type_arg));
      convert_type(type);
    }
  }
  else if(expr.id()==ID_gcc_builtin_va_arg)
  {
    convert_type(expr.type());
  }
  else if(expr.id()==ID_generic_selection)
  {
    assert(expr.operands().size()==1);

    irept::subt &generic_associations=
      expr.add(ID_generic_associations).get_sub();

    Forall_irep(it, generic_associations)
    {
      convert_expr(static_cast<exprt &>(it->add(ID_value)));
      convert_type(static_cast<typet &>(it->add(ID_type_arg)));
    }
예제 #2
0
파일: cvc_conv.cpp 프로젝트: diffblue/cbmc
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)
예제 #3
0
파일: cvc_conv.cpp 프로젝트: diffblue/cbmc
void cvc_convt::convert_array_index(const exprt &expr)
{
    if(expr.type()==gen_array_index_type())
    {
        convert_expr(expr);
    }
    else
    {
        exprt tmp(ID_typecast, gen_array_index_type());
        tmp.copy_to_operands(expr);
        convert_expr(tmp);
    }
}
예제 #4
0
void ansi_c_convertt::convert_declaration(ansi_c_declarationt &declaration)
{
  c_storage_spect c_storage_spec;

  convert_type(declaration.type(), c_storage_spec);

  declaration.set_is_inline(c_storage_spec.is_inline);
  declaration.set_is_static(c_storage_spec.is_static);
  declaration.set_is_extern(c_storage_spec.is_extern);
  declaration.set_is_thread_local(c_storage_spec.is_thread_local);
  declaration.set_is_register(c_storage_spec.is_register);

  // do not overwrite is_typedef -- it's done by the parser
  // typedefs are macros
  if(declaration.get_is_typedef())
    declaration.set_is_macro(true);

  if(declaration.value().is_not_nil())
  {
    if(declaration.value().type().id()==ID_code)
      convert_code(to_code(declaration.value()));
    else
      convert_expr(declaration.value());
  }
}
예제 #5
0
파일: cvc_conv.cpp 프로젝트: diffblue/cbmc
void cvc_convt::convert_as_bv(const exprt &expr)
{
    if(expr.type().id()==ID_bool)
    {
        if(expr.is_true())
            out << "0bin1";
        else if(expr.is_false())
            out << "0bin0";
        else
        {
            out << "IF ";
            convert_expr(expr);
            out << " THEN 0bin1 ELSE 0bin0 ENDIF";
        }
    }
    else
        convert_expr(expr);
}
예제 #6
0
파일: cvc_conv.cpp 프로젝트: diffblue/cbmc
literalt cvc_convt::convert(const exprt &expr)
{
    //out << "%% E: " << expr << std::endl;

    if(expr.type().id()!=ID_bool)
    {
        std::string msg="cvc_convt::convert got "
                        "non-boolean expression: ";
        msg+=expr.pretty();
        throw msg;
    }

    // Three special cases in which we don't need to generate
    // a handle.

    if(expr.is_true())
        return const_literal(true);
    else if(expr.is_false())
        return const_literal(false);
    else if(expr.id()==ID_literal)
        return to_literal_expr(expr).get_literal();

    // Generate new handle

    literalt l(no_boolean_variables, false);
    no_boolean_variables++;

    find_symbols(expr);

    // define new handle
    out << "ASSERT ";
    convert_literal(l);
    out << " <=> (";
    convert_expr(expr);
    out << ");" << std::endl << std::endl;

    return l;
}
예제 #7
0
파일: cvc_conv.cpp 프로젝트: diffblue/cbmc
void cvc_convt::convert_address_of_rec(const exprt &expr)
{
    if(expr.id()==ID_symbol ||
            expr.id()==ID_constant ||
            expr.id()==ID_string_constant)
    {
        out
                << "(# object:="
                << pointer_logic.add_object(expr)
                << ", offset:="
                << bin_zero(config.ansi_c.pointer_width) << " #)";
    }
    else if(expr.id()==ID_index)
    {
        if(expr.operands().size()!=2)
            throw "index takes two operands";

        const exprt &array=expr.op0();
        const exprt &index=expr.op1();

        if(index.is_zero())
        {
            if(array.type().id()==ID_pointer)
                convert_expr(array);
            else if(array.type().id()==ID_array)
                convert_address_of_rec(array);
            else
                assert(false);
        }
        else
        {
            out << "(LET P: ";
            out << cvc_pointer_type();
            out << " = ";

            if(array.type().id()==ID_pointer)
                convert_expr(array);
            else if(array.type().id()==ID_array)
                convert_address_of_rec(array);
            else
                assert(false);

            out << " IN P WITH .offset:=BVPLUS("
                << config.ansi_c.pointer_width
                << ", P.offset, ";
            convert_expr(index);
            out << "))";
        }
    }
    else if(expr.id()==ID_member)
    {
        if(expr.operands().size()!=1)
            throw "member takes one operand";

        const exprt &struct_op=expr.op0();

        out << "(LET P: ";
        out << cvc_pointer_type();
        out << " = ";

        convert_address_of_rec(struct_op);

        const irep_idt &component_name=
            to_member_expr(expr).get_component_name();

        mp_integer offset=member_offset(
                              to_struct_type(struct_op.type()),
                              component_name, ns);

        typet index_type(ID_unsignedbv);
        index_type.set(ID_width, config.ansi_c.pointer_width);

        exprt index=from_integer(offset, index_type);

        out << " IN P WITH .offset:=BVPLUS("
            << config.ansi_c.pointer_width
            << ", P.offset, ";
        convert_expr(index);
        out << "))";
    }
    else
        throw "don't know how to take address of: "+expr.id_string();
}