Beispiel #1
0
bool to_integer(const exprt &expr, mp_integer &int_value)
{
  if(!expr.is_constant())
    return true;

  const std::string &value = expr.value().as_string();
  const irep_idt &type_id = expr.type().id();

  if(type_id == "pointer")
  {
    if(value == "NULL")
    {
      int_value = 0;
      return false;
    }
  }
  else if(type_id == "c_enum" || type_id == "symbol")
  {
    int_value = string2integer(value);
    return false;
  }
  else if(type_id == "unsignedbv")
  {
    int_value = binary2integer(value, false);
    return false;
  }
  else if(type_id == "signedbv")
  {
    int_value = binary2integer(value, true);
    return false;
  }

  return true;
}
void convert_integer_literal(
  const std::string &src,
  exprt &dest,
  unsigned base)
{
  bool is_unsigned=false;
  unsigned long_cnt=0;

  for(unsigned i=src.size(); i!=0; i--)
  {
    char ch=src[i-1];
    if(ch=='u' || ch=='U')
      is_unsigned=true;
    else if(ch=='l' || ch=='L')
      long_cnt++;
    else
      break;
  }

  mp_integer value;

  if(base==10)
  {
    dest.value(src);
    value=string2integer(src, 10);
  }
  else if(base==8)
  {
    dest.hex_or_oct(true);
    value=string2integer(src, 8);
  }
  else
  {
    dest.hex_or_oct(true);
    std::string without_prefix(src, 2, std::string::npos);
    value=string2integer(without_prefix, 16);
  }

  typet type;
  irep_idt cpp_type;

  if(is_unsigned)
    type=typet("unsignedbv");
  else
    type=typet("signedbv");

  if(long_cnt==0) {
    type.width(config.ansi_c.int_width);

    if(!is_unsigned)
      cpp_type="signed_int";
    else
      cpp_type="unsigned_int";

  } else if(long_cnt==1) {
    type.width(config.ansi_c.long_int_width);

    if(!is_unsigned)
      cpp_type="signed_long_int";
    else
      cpp_type="unsigned_long_int";

  } else {
    type.width(config.ansi_c.long_long_int_width);

    if(!is_unsigned)
      cpp_type="signed_long_long_int";
    else
      cpp_type="unsigned_long_long_int";
  }

  type.set("#cpp_type", cpp_type);

  dest=from_integer(value, type);

  dest.cformat(src);

}
bool c_typecheck_baset::zero_initializer(exprt &value, const typet &type) const
{
  const std::string &type_id = type.id_string();

  if(type_id == "bool")
  {
    value.make_false();
    return false;
  }
  if(
    type_id == "unsignedbv" || type_id == "signedbv" || type_id == "floatbv" ||
    type_id == "fixedbv" || type_id == "pointer")
  {
    value = gen_zero(type);
    return false;
  }
  else if(type_id == "code")
    return false;
  else if(type_id == "c_enum" || type_id == "incomplete_c_enum")
  {
    value = exprt("constant", type);
    value.value(i2string(0));
    return false;
  }
  else if(type_id == "array")
  {
    const array_typet &array_type = to_array_type(type);

    exprt tmpval;
    if(zero_initializer(tmpval, array_type.subtype()))
      return true;

    const exprt &size_expr = array_type.size();

    if(size_expr.id() == "infinity")
    {
    }
    else
    {
      mp_integer size;

      if(to_integer(size_expr, size))
        return true;

      // Permit GCC zero sized arrays; disallow negative sized arrays.
      // Cringe slightly when doing it though.
      if(size < 0)
        return true;
    }

    value = exprt("array_of", type);
    value.move_to_operands(tmpval);

    return false;
  }
  else if(type_id == "struct")
  {
    const irept::subt &components = type.components().get_sub();

    value = exprt("struct", type);

    forall_irep(it, components)
    {
      exprt tmp;

      if(zero_initializer(tmp, (const typet &)it->type()))
        return true;

      value.move_to_operands(tmp);
    }

    return false;
  }
Beispiel #4
0
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()));
  }
}