コード例 #1
0
void boolbvt::convert_index(
  const exprt &array,
  const mp_integer &index,
  bvt &bv)
{
  const array_typet &array_type=
    to_array_type(ns.follow(array.type()));

  unsigned width=boolbv_width(array_type.subtype());

  if(width==0)
    return conversion_failed(array, bv);

  bv.resize(width);
  
  const bvt &tmp=convert_bv(array); // recursive call

  mp_integer offset=index*width;

  if(offset>=0 &&
     offset+width<=mp_integer(tmp.size()))
  {
    // in bounds
    for(unsigned i=0; i<width; i++)
      bv[i]=tmp[integer2long(offset+i)];
  }
  else
  {
    // out of bounds
    for(unsigned i=0; i<width; i++)
      bv[i]=prop.new_variable();
  }
}
コード例 #2
0
ファイル: c_typecheck_type.cpp プロジェクト: dcattaruzza/cbmc
typet c_typecheck_baset::enum_constant_type(
  const mp_integer &min_value,
  const mp_integer &max_value) const
{
  if(config.ansi_c.mode==configt::ansi_ct::flavourt::VISUAL_STUDIO)
  {
    return signed_int_type();
  }
  else
  {
    // enum constants are at least 'int', but may be made larger.
    // 'Packing' has no influence.
    if(max_value<(mp_integer(1)<<(config.ansi_c.int_width-1)) &&
       min_value>=-(mp_integer(1)<<(config.ansi_c.int_width-1)))
      return signed_int_type();
    else if(max_value<(mp_integer(1)<<config.ansi_c.int_width) &&
            min_value>=0)
      return unsigned_int_type();
    else if(max_value<(mp_integer(1)<<config.ansi_c.long_int_width) &&
            min_value>=0)
      return unsigned_long_int_type();
    else if(max_value<(mp_integer(1)<<config.ansi_c.long_long_int_width) &&
            min_value>=0)
      return unsigned_long_long_int_type();
    else if(max_value<(mp_integer(1)<<(config.ansi_c.long_int_width-1)) &&
            min_value>=-(mp_integer(1)<<(config.ansi_c.long_int_width-1)))
      return signed_long_int_type();
    else
      return signed_long_long_int_type();
  }
}
コード例 #3
0
exprt c_typecheck_baset::do_initializer_rec(
  const exprt &value,
  const typet &type,
  bool force_constant)
{
  const typet &full_type=follow(type);

  if(full_type.id()==ID_incomplete_struct)
  {
    err_location(value);
    error() << "type `" << to_string(full_type)
            << "' is still incomplete -- cannot initialize" << eom;
    throw 0;
  }

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

  if(value.id()==ID_array &&
     value.get_bool(ID_C_string_constant) &&
     full_type.id()==ID_array &&
     (full_type.subtype().id()==ID_signedbv ||
      full_type.subtype().id()==ID_unsignedbv) &&
      full_type.subtype().get(ID_width)==value.type().subtype().get(ID_width))
  {
    exprt tmp=value;

    // adjust char type
    tmp.type().subtype()=full_type.subtype();

    Forall_operands(it, tmp)
      it->type()=full_type.subtype();

    if(full_type.id()==ID_array &&
       to_array_type(full_type).is_complete())
    {
      // check size
      mp_integer array_size;
      if(to_integer(to_array_type(full_type).size(), array_size))
      {
        err_location(value);
        error() << "array size needs to be constant, got "
                << to_string(to_array_type(full_type).size()) << eom;
        throw 0;
      }

      if(array_size<0)
      {
        err_location(value);
        error() << "array size must not be negative" << eom;
        throw 0;
      }

      if(mp_integer(tmp.operands().size())>array_size)
      {
        // cut off long strings. gcc does a warning for this
        tmp.operands().resize(integer2size_t(array_size));
        tmp.type()=type;
      }
      else if(mp_integer(tmp.operands().size())<array_size)
      {
        // fill up
        tmp.type()=type;
        exprt zero=
          zero_initializer(
            full_type.subtype(),
            value.source_location(),
            *this,
            get_message_handler());
        tmp.operands().resize(integer2size_t(array_size), zero);
      }
    }

    return tmp;
  }

  if(value.id()==ID_string_constant &&
     full_type.id()==ID_array &&
     (full_type.subtype().id()==ID_signedbv ||
      full_type.subtype().id()==ID_unsignedbv) &&
      full_type.subtype().get(ID_width)==char_type().get(ID_width))
  {
    // will go away, to be replaced by the above block

    string_constantt tmp1=to_string_constant(value);
    // adjust char type
    tmp1.type().subtype()=full_type.subtype();

    exprt tmp2=tmp1.to_array_expr();

    if(full_type.id()==ID_array &&
       to_array_type(full_type).is_complete())
    {
      // check size
      mp_integer array_size;
      if(to_integer(to_array_type(full_type).size(), array_size))
      {
        err_location(value);
        error() << "array size needs to be constant, got "
                << to_string(to_array_type(full_type).size()) << eom;
        throw 0;
      }

      if(array_size<0)
      {
        err_location(value);
        error() << "array size must not be negative" << eom;
        throw 0;
      }

      if(mp_integer(tmp2.operands().size())>array_size)
      {
        // cut off long strings. gcc does a warning for this
        tmp2.operands().resize(integer2size_t(array_size));
        tmp2.type()=type;
      }
      else if(mp_integer(tmp2.operands().size())<array_size)
      {
        // fill up
        tmp2.type()=type;
        exprt zero=
          zero_initializer(
            full_type.subtype(),
            value.source_location(),
            *this,
            get_message_handler());
        tmp2.operands().resize(integer2size_t(array_size), zero);
      }
    }

    return tmp2;
  }

  if(full_type.id()==ID_array &&
     to_array_type(full_type).size().is_nil())
  {
    err_location(value);
    error() << "type `" << to_string(full_type)
            << "' cannot be initialized with `" << to_string(value)
            << "'" << eom;
    throw 0;
  }

  if(value.id()==ID_designated_initializer)
  {
    err_location(value);
    error() << "type `" << to_string(full_type)
            << "' cannot be initialized with designated initializer"
            << eom;
    throw 0;
  }

  exprt result=value;
  implicit_typecast(result, type);
  return result;
}
コード例 #4
0
ファイル: convert_float_literal.cpp プロジェクト: Dthird/CBMC
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;
}
コード例 #5
0
bvt boolbvt::convert_byte_update(const byte_update_exprt &expr)
{
  if(expr.operands().size()!=3)
    throw "byte_update takes three operands";
    
  const exprt &op=expr.op0();
  const exprt &offset_expr=expr.offset();
  const exprt &value=expr.value();

  bool little_endian;
  
  if(expr.id()==ID_byte_update_little_endian)
    little_endian=true;
  else if(expr.id()==ID_byte_update_big_endian)
    little_endian=false;
  else
    assert(false);

  bvt bv=convert_bv(op);
  
  const bvt &value_bv=convert_bv(value);
  std::size_t update_width=value_bv.size();
  std::size_t byte_width=8;
  
  if(update_width>bv.size())
    update_width=bv.size();

  // see if the byte number is constant

  mp_integer index;
  if(!to_integer(offset_expr, index))
  {
    // yes!
    mp_integer offset=index*8;
    
    if(offset+update_width>mp_integer(bv.size()) || offset<0)
    {
      // out of bounds
    }
    else
    {
      if(little_endian)
      {
        for(std::size_t i=0; i<update_width; i++)
          bv[integer2size_t(offset+i)]=value_bv[i];
      }
      else
      {
        endianness_mapt map_op(op.type(), false, ns);
        endianness_mapt map_value(value.type(), false, ns);
        
        std::size_t offset_i=integer2unsigned(offset);
        
        for(std::size_t i=0; i<update_width; i++)
        {
          size_t index_op=map_op.map_bit(offset_i+i);
          size_t index_value=map_value.map_bit(i);

          assert(index_op<bv.size());
          assert(index_value<value_bv.size());
          
          bv[index_op]=value_bv[index_value];
        }
      }
    }

    return bv;
  }

  // byte_update with variable index
  for(std::size_t offset=0; offset<bv.size(); offset+=byte_width)
  {
    // index condition
    equal_exprt equality;
    equality.lhs()=offset_expr;
    equality.rhs()=from_integer(offset/byte_width, offset_expr.type());
    literalt equal=convert(equality);
    
    endianness_mapt map_op(op.type(), little_endian, ns);
    endianness_mapt map_value(value.type(), little_endian, ns);

    for(std::size_t bit=0; bit<update_width; bit++)
      if(offset+bit<bv.size())
      {
        std::size_t bv_o=map_op.map_bit(offset+bit);
        std::size_t value_bv_o=map_value.map_bit(bit);
        
        bv[bv_o]=prop.lselect(equal, value_bv[value_bv_o], bv[bv_o]);
      }
  }
  
  return bv;
}
コード例 #6
0
void goto_convertt::do_prob_coin(
  const exprt &lhs,
  const exprt &function,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  const irep_idt &identifier=function.get(ID_identifier);

  // make it a side effect if there is an LHS
  if(arguments.size()!=2) 
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected to have two arguments";
  }
  
  if(lhs.is_nil())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected to have LHS";
  }

  exprt rhs=side_effect_exprt("prob_coin", lhs.type());
  rhs.add_source_location()=function.source_location();

  if(lhs.type()!=bool_typet())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected bool";
  }

  if(arguments[0].type().id()!=ID_unsignedbv ||
     arguments[0].id()!=ID_constant)
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected first "
          "operand to be a constant literal of type unsigned long";
  }

  mp_integer num, den;

  if(to_integer(arguments[0], num) ||
     to_integer(arguments[1], den))
  {
    err_location(function);
    throw "error converting operands";
  }

  if(num-den > mp_integer(0))
  {
    err_location(function);
    throw "probability has to be smaller than 1";
  }

  if(den == mp_integer(0))
  {
    err_location(function);
    throw "denominator may not be zero";
  }

  rationalt numerator(num), denominator(den);
  rationalt prob = numerator / denominator;

  rhs.copy_to_operands(from_rational(prob));

  code_assignt assignment(lhs, rhs);
  assignment.add_source_location()=function.source_location();
  copy(assignment, ASSIGN, dest);
}
コード例 #7
0
ファイル: c_typecheck_type.cpp プロジェクト: dcattaruzza/cbmc
typet c_typecheck_baset::enum_underlying_type(
  const mp_integer &min_value,
  const mp_integer &max_value,
  bool is_packed) const
{
  if(config.ansi_c.mode==configt::ansi_ct::flavourt::VISUAL_STUDIO)
  {
    return signed_int_type();
  }
  else
  {
    if(min_value<0)
    {
      // We'll want a signed type.

      if(is_packed)
      {
        // If packed, there are smaller options.
        if(max_value<(mp_integer(1)<<(config.ansi_c.char_width-1)) &&
           min_value>=-(mp_integer(1)<<(config.ansi_c.char_width-1)))
          return signed_char_type();
        else if(max_value<(mp_integer(1)<<(config.ansi_c.short_int_width-1)) &&
                min_value>=-(mp_integer(1)<<(config.ansi_c.short_int_width-1)))
          return signed_short_int_type();
      }

      if(max_value<(mp_integer(1)<<(config.ansi_c.int_width-1)) &&
         min_value>=-(mp_integer(1)<<(config.ansi_c.int_width-1)))
        return signed_int_type();
      else if(max_value<(mp_integer(1)<<(config.ansi_c.long_int_width-1)) &&
              min_value>=-(mp_integer(1)<<(config.ansi_c.long_int_width-1)))
        return signed_long_int_type();
      else
        return signed_long_long_int_type();
    }
    else
    {
      // We'll want an unsigned type.

      if(is_packed)
      {
        // If packed, there are smaller options.
        if(max_value<(mp_integer(1)<<config.ansi_c.char_width))
          return unsigned_char_type();
        else if(max_value<(mp_integer(1)<<config.ansi_c.short_int_width))
          return unsigned_short_int_type();
      }

      if(max_value<(mp_integer(1)<<config.ansi_c.int_width))
        return unsigned_int_type();
      else if(max_value<(mp_integer(1)<<config.ansi_c.long_int_width))
        return unsigned_long_int_type();
      else
        return unsigned_long_long_int_type();
    }
  }
}
コード例 #8
0
exprt convert_float_literal(const std::string &src)
{
  mp_integer significand;
  mp_integer exponent;
  bool is_float, is_long, is_fixed, is_accum;
  unsigned base;
  
  parse_float(src, significand, exponent, base, is_float, is_long, is_fixed, is_accum);

  exprt result=exprt(ID_constant);
  
  result.set(ID_C_cformat, src);
  
  // In ANSI-C, float literals are double by default
  // unless marked with 'f'.

  if(is_float)
  {
    result.type()=float_type();
    result.type().set(ID_C_cpp_type, ID_float);
  }
  else if(is_long)
  {
    result.type()=long_double_type();
    result.type().set(ID_C_cpp_type, ID_long_double);
  }
  else if(is_fixed)
  {
    result.type()=fixed_type();
    result.type().set(ID_C_cpp_type, ID_fixed);
  }
  else if(is_accum)
  {
    result.type()=accum_type();
    result.type().set(ID_C_cpp_type, ID_accum);
  }
  else
  {
    result.type()=double_type(); // default
    result.type().set(ID_C_cpp_type, ID_double);
  }


  if(config.ansi_c.use_fixed_for_float || is_fixed || is_accum)
  {
    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(is_fixed)
    {
      fraction_bits = width - 1;
    }
    else if(is_accum)
    {
      fraction_bits = width - 9;
    }
    else 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()));  
  }
  
  return result;
}
コード例 #9
0
ファイル: ieee_float.cpp プロジェクト: eigold/cbmc
void ieee_floatt::align()
{
  // NaN?
  if(NaN_flag)
  {
    fraction=0;
    exponent=0;
    sign_flag=false;
    return;
  }

  // do sign
  if(fraction<0)
  {
    sign_flag=!sign_flag;
    fraction=-fraction;
  }

  // zero?
  if(fraction==0)
  {
    exponent=0;
    return;
  }

  // 'usual case'
  mp_integer f_power=power(2, spec.f);
  mp_integer f_power_next=power(2, spec.f+1);

  std::size_t lowPower2=fraction.floorPow2();
  mp_integer exponent_offset=0;

  if(lowPower2<spec.f) // too small
  {
    exponent_offset-=(spec.f-lowPower2);

    assert(fraction*power(2, (spec.f-lowPower2))>=f_power);
    assert(fraction*power(2, (spec.f-lowPower2))<f_power_next);
  }
  else if(lowPower2>spec.f)  // too large
  {
    exponent_offset+=(lowPower2-spec.f);

    assert(fraction/power(2, (lowPower2-spec.f))>=f_power);
    assert(fraction/power(2, (lowPower2-spec.f))<f_power_next);
  }

  mp_integer biased_exponent=exponent+exponent_offset+spec.bias();

  // exponent too large (infinity)?
  if(biased_exponent>=spec.max_exponent())
  {
    // we need to consider the rounding mode here
    switch(rounding_mode)
    {
    case UNKNOWN:
    case NONDETERMINISTIC:
    case ROUND_TO_EVEN:
      infinity_flag=true;
      break;

    case ROUND_TO_MINUS_INF:
      // the result of the rounding is never larger than the argument
      if(sign_flag)
        infinity_flag=true;
      else
        make_fltmax();
      break;

    case ROUND_TO_PLUS_INF:
      // the result of the rounding is never smaller than the argument
      if(sign_flag)
      {
        make_fltmax();
        sign_flag=true; // restore sign
      }
      else
        infinity_flag=true;
      break;

    case ROUND_TO_ZERO:
      if(sign_flag)
      {
        make_fltmax();
        sign_flag=true; // restore sign
      }
      else
        make_fltmax(); // positive
      break;
    }

    return; // done
  }
  else if(biased_exponent<=0) // exponent too small?
  {
    // produce a denormal (or zero)
    mp_integer new_exponent=mp_integer(1)-spec.bias();
    exponent_offset=new_exponent-exponent;
  }

  exponent+=exponent_offset;

  if(exponent_offset>0)
  {
    divide_and_round(fraction, power(2, exponent_offset));

    // rounding might make the fraction too big!
    if(fraction==f_power_next)
    {
      fraction=f_power;
      ++exponent;
    }
  }
  else if(exponent_offset<0)
    fraction*=power(2, -exponent_offset);

  if(fraction==0)
    exponent=0;
}
コード例 #10
0
ファイル: ieee_float.cpp プロジェクト: eigold/cbmc
std::string ieee_floatt::to_string_decimal(std::size_t precision) const
{
  std::string result;

  if(sign_flag)
    result+='-';

  if((NaN_flag || infinity_flag) && !sign_flag)
    result+='+';

  // special cases
  if(NaN_flag)
    result+="NaN";
  else if(infinity_flag)
    result+="inf";
  else if(is_zero())
  {
    result+='0';

    // add zeros, if needed
    if(precision>0)
    {
      result+='.';
      for(std::size_t i=0; i<precision; i++)
        result+='0';
    }
  }
  else
  {
    mp_integer _exponent, _fraction;
    extract_base2(_fraction, _exponent);

    // convert to base 10
    if(_exponent>=0)
    {
      result+=integer2string(_fraction*power(2, _exponent));

      // add dot and zeros, if needed
      if(precision>0)
      {
        result+='.';
        for(std::size_t i=0; i<precision; i++)
          result+='0';
      }
    }
    else
    {
      #if 1
      mp_integer position=-_exponent;

      // 10/2=5 -- this makes it base 10
      _fraction*=power(5, position);

      // apply rounding
      if(position>precision)
      {
        mp_integer r=power(10, position-precision);
        mp_integer remainder=_fraction%r;
        _fraction/=r;
        // not sure if this is the right kind of rounding here
        if(remainder>=r/2)
          ++_fraction;
        position=precision;
      }

      std::string tmp=integer2string(_fraction);

      // pad with zeros from the front, if needed
      while(mp_integer(tmp.size())<=position) tmp="0"+tmp;

      std::size_t dot=tmp.size()-integer2size_t(position);
      result+=std::string(tmp, 0, dot)+'.';
      result+=std::string(tmp, dot, std::string::npos);

      // append zeros if needed
      for(mp_integer i=position; i<precision; ++i)
        result+='0';
      #else

      result+=integer2string(_fraction);

      if(_exponent!=0)
        result+="*2^"+integer2string(_exponent);

      #endif
    }
  }

  return result;
}
コード例 #11
0
void ieee_floatt::align()
{
  // NaN?
  if(NaN)
  {
    fraction=0;
    exponent=0;
    sign=false;
    return;
  }

  // do sign
  if(fraction<0)
  {
    sign=!sign;
    fraction=-fraction;
  }

  // zero?
  if(fraction==0)
  {
    exponent=0;
    return;
  }

  // 'usual case'

  mp_integer f_power=power(2, spec.f);
  mp_integer f_power_next=power(2, spec.f+1);

  mp_integer exponent_offset=0;

  if(fraction<f_power) // too small?
  {
    mp_integer tmp_fraction=fraction;

    while(tmp_fraction<f_power)
    {
      tmp_fraction*=2;
      --exponent_offset;
    }
  }
  else if(fraction>=f_power_next) // too big?
  {
    mp_integer tmp_fraction=fraction;

    while(tmp_fraction>=f_power_next)
    {
      tmp_fraction/=2;
      ++exponent_offset;
    }
  }

  mp_integer biased_exponent=exponent+exponent_offset+spec.bias();

  // exponent too large (infinity)?
  if(biased_exponent>=spec.max_exponent())
    infinity=true;
  else if(biased_exponent<=0) // exponent too small?
  {
    // produce a denormal (or zero)
    mp_integer new_exponent=mp_integer(1)-spec.bias();
    exponent_offset=new_exponent-exponent;
  }

  exponent+=exponent_offset;

  if(exponent_offset>0)
  {
    divide_and_round(fraction, power(2, exponent_offset));

    // rounding might make the fraction too big!
    if(fraction==f_power_next)
    {
      fraction=f_power;
      ++exponent;
    }
  }
  else if(exponent_offset<0)
    fraction*=power(2, -exponent_offset);

  if(fraction==0)
    exponent=0;
}
コード例 #12
0
std::string ieee_floatt::format(const format_spect &format_spec) const
{
  std::string result;

  if(sign) result+="-";
  
  if((NaN || infinity) && !sign) result+="+";

  // special cases
  if(NaN)
    result+="NaN";
  else if(infinity)
    result+="inf";
  else if(is_zero())
  {
    result+="0";

    // add zeros, if needed
    if(format_spec.precision>0)
    {
      result+='.';
      for(unsigned i=0; i<format_spec.precision; i++)
        result+='0';
    }
  }
  else
  {
    mp_integer _exponent, _fraction;
    extract(_fraction, _exponent);

    // convert to base 10
    if(_exponent>=0)
    {
      result+=integer2string(_fraction*power(2, _exponent));
      
      // add zeros, if needed
      if(format_spec.precision>0)
      {
        result+='.';
        for(unsigned i=0; i<format_spec.precision; i++)
          result+='0';
      }
    }
    else
    {
      #if 1
      mp_integer position=-_exponent;

      // 10/2=5 -- this makes it base 10
      _fraction*=power(5, position);

      // apply rounding
      if(position>format_spec.precision)
      {
        mp_integer r=power(10, position-format_spec.precision);
        mp_integer remainder=_fraction%r;
        _fraction/=r;
        // not sure if this is the right kind of rounding here
        if(remainder>=r/2) ++_fraction;
        position=format_spec.precision;
      }

      std::string tmp=integer2string(_fraction);

      // pad with zeros from the front, if needed
      while(mp_integer(tmp.size())<=position) tmp="0"+tmp;

      unsigned dot=tmp.size()-integer2long(position);
      result+=std::string(tmp, 0, dot)+'.';
      result+=std::string(tmp, dot, std::string::npos);

      // append zeros if needed
      for(mp_integer i=position; i<format_spec.precision; ++i)
        result+='0';
      #else

      result+=integer2string(_fraction);

      if(_exponent!=0)
        result+="*2^"+integer2string(_exponent);

      #endif
    }
  }

  while(result.size()<format_spec.min_width)
    result=" "+result;

  return result;
}
コード例 #13
0
bool clang_c_convertert::convert_float_literal(
  const clang::FloatingLiteral &floating_literal,
  exprt &dest)
{
  if(!config.ansi_c.use_fixed_for_float)
  {
    std::cerr << "floatbv unsupported, sorry" << std::endl;
    return false;
  }

  typet type;
  if(get_type(floating_literal.getType(), type))
    return true;

  llvm::APFloat val = floating_literal.getValue();

  llvm::SmallVector<char, 32> string;
  val.toString(string, 32, 0);

  unsigned width = bv_width(type);
  mp_integer value;
  std::string float_string;

  if(!val.isInfinity())
  {
    mp_integer significand;
    mp_integer exponent;

    float_string = parse_float(string, significand, exponent);

    unsigned fraction_bits;
    const std::string &integer_bits = type.integer_bits().as_string();

    if (integer_bits == "")
      fraction_bits = width / 2;
    else
      fraction_bits = width - atoi(integer_bits.c_str());

    mp_integer factor = mp_integer(1) << fraction_bits;
    value = significand * factor;

    if(exponent < 0)
      value /= power(10, -exponent);
    else
    {
      value *= power(10, exponent);

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

  dest =
    constant_exprt(
      integer2binary(value, bv_width(type)),
      float_string,
      type);

  return false;
}
コード例 #14
0
ファイル: convert_float_literal.cpp プロジェクト: esbmc/esbmc
void convert_float_literal(const std::string &src, exprt &dest)
{
  mp_integer significand;
  mp_integer exponent;
  bool is_float, is_long;
  unsigned base;

  parse_float(src, significand, exponent, base, is_float, is_long);

  dest = exprt("constant");

  dest.cformat(src);

  if(is_float)
  {
    dest.type() = float_type();
    dest.type().set("#cpp_type", "float");
  }
  else if(is_long)
  {
    dest.type() = long_double_type();
    dest.type().set("#cpp_type", "long_double");
  }
  else
  {
    dest.type() = double_type();
    dest.type().set("#cpp_type", "double");
  }

  if(config.ansi_c.use_fixed_for_float)
  {
    unsigned width = atoi(dest.type().width().c_str());
    unsigned fraction_bits;
    const std::string &integer_bits = dest.type().integer_bits().as_string();

    if(integer_bits == "")
      fraction_bits = width / 2;
    else
      fraction_bits = width - atoi(integer_bits.c_str());

    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);
        }
      }
    }

    dest.value(integer2binary(value, width));
  }
  else
  {
    ieee_floatt a;

    a.spec = to_floatbv_type(dest.type());

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

    dest.value(integer2binary(a.pack(), a.spec.width()));
  }
}
コード例 #15
0
mp_integer pointer_offset_size(
  const namespacet &ns,
  const typet &type)
{
  if(type.id()==ID_array)
  {
    mp_integer sub=pointer_offset_size(ns, type.subtype());
  
    // get size
    const exprt &size=to_array_type(type).size();

    // constant?
    mp_integer i;
    
    if(to_integer(size, i))
      return -1; // we cannot distinguish the elements
    
    return sub*i;
  }
  else if(type.id()==ID_struct)
  {
    const struct_typet &struct_type=to_struct_type(type);
    const struct_typet::componentst &components=
      struct_type.components();
      
    mp_integer result=0;
    unsigned bit_field_bits=0;
    
    for(struct_typet::componentst::const_iterator
        it=components.begin();
        it!=components.end();
        it++)
    {
      if(it->get_is_bit_field())
      {
        bit_field_bits+=it->type().get_int(ID_width);
      }
      else
      {
        if(bit_field_bits!=0)
        {
          result+=bit_field_bits/8;
          bit_field_bits=0;
        }
        
        const typet &subtype=it->type();
        mp_integer sub_size=pointer_offset_size(ns, subtype);
        if(sub_size==-1) return -1;
        result+=sub_size;
      }
    }
    
    return result;
  }
  else if(type.id()==ID_union)
  {
    const union_typet &union_type=to_union_type(type);
    const union_typet::componentst &components=
      union_type.components();
      
    mp_integer result=0;

    // compute max
    
    for(union_typet::componentst::const_iterator
        it=components.begin();
        it!=components.end();
        it++)
    {
      const typet &subtype=it->type();
      mp_integer sub_size=pointer_offset_size(ns, subtype);
      if(sub_size>result) result=sub_size;
    }
    
    return result;
  }
  else if(type.id()==ID_signedbv ||
          type.id()==ID_unsignedbv ||
          type.id()==ID_fixedbv ||
          type.id()==ID_floatbv ||
          type.id()==ID_bv ||
          type.id()==ID_c_enum)
  {
    unsigned width=to_bitvector_type(type).get_width();
    unsigned bytes=width/8;
    if(bytes*8!=width) bytes++;
    return bytes;
  }
  else if(type.id()==ID_bool)
    return 1;
  else if(type.id()==ID_pointer)
  {
    unsigned width=config.ansi_c.pointer_width;
    unsigned bytes=width/8;
    if(bytes*8!=width) bytes++;
    return bytes;
  }
  else if(type.id()==ID_symbol)
    return pointer_offset_size(ns, ns.follow(type));
  else if(type.id()==ID_code)
    return 0;
  else
    return mp_integer(-1);
}