示例#1
0
bool check_c_implicit_typecast(
  const typet &src_type,
  const typet &dest_type)
{
  // check qualifiers  

  if(src_type.id()==ID_pointer && dest_type.id()==ID_pointer &&
     src_type.subtype().get_bool(ID_C_constant) &&
     !dest_type.subtype().get_bool(ID_C_constant))
    return true;

  if(src_type==dest_type) return false;
  
  const irep_idt &src_type_id=src_type.id();

  if(src_type_id==ID_natural)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_integer)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_pointer) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_real)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_rational)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_bool)
  {
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_pointer) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_c_enum) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_unsignedbv ||
          src_type_id==ID_signedbv ||
          src_type_id==ID_c_enum ||
          src_type_id==ID_incomplete_c_enum)
  {
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_rational) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_pointer) return false;
    if(dest_type.id()==ID_c_enum) return false;
    if(dest_type.id()==ID_incomplete_c_enum) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_floatbv ||
          src_type_id==ID_fixedbv)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_rational) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_array ||
          src_type_id==ID_pointer)
  {
    if(dest_type.id()==ID_pointer)
    {
      const irept &dest_subtype=dest_type.subtype();
      const irept &src_subtype =src_type.subtype();

      if(src_subtype==dest_subtype)
        return false;
      else if(is_void_pointer(src_type) || // from void to anything
              is_void_pointer(dest_type))  // to void from anything
        return false;
    }
    
    if(dest_type.id()==ID_array &&
       src_type.subtype()==dest_type.subtype()) return false;

    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
  }
  else if(src_type_id==ID_vector)
  {
    if(dest_type.id()==ID_vector)
      return false;
  }
  else if(src_type_id==ID_complex)
  {
    if(dest_type.id()==ID_complex)
    {
      // We convert between complex types if we convert between
      // their component types.
      if(!check_c_implicit_typecast(src_type.subtype(), dest_type.subtype()))
        return false;
    }
  }

  return true;
}
示例#2
0
void c_typecastt::implicit_typecast_followed(
  exprt &expr,
  const typet &src_type,
  const typet &dest_type)
{
  if(dest_type.id()==ID_union)

  // do transparent union
  if(dest_type.id()==ID_union &&
     dest_type.get_bool(ID_C_transparent_union) &&
     src_type.id()!=ID_union)
  {
    // The argument corresponding to a transparent union type can be of any
    // type in the union; no explicit cast is required.
    
    // Check union members.
    const union_typet &dest_union_type=to_union_type(dest_type);

    for(union_typet::componentst::const_iterator
        it=dest_union_type.components().begin();
        it!=dest_union_type.components().end();
        it++)
    {
      if(!check_c_implicit_typecast(src_type, it->type()))
      {
        // build union constructor
        exprt union_expr(ID_union, dest_union_type);
        union_expr.move_to_operands(expr);
        union_expr.set(ID_component_name, it->get_name());
        expr=union_expr;
        return; // ok
      }
    }
  }

  if(dest_type.id()==ID_pointer)
  {
    // special case: 0 == NULL

    if(expr.is_zero() && (
       src_type.id()==ID_unsignedbv ||
       src_type.id()==ID_signedbv ||
       src_type.id()==ID_natural ||
       src_type.id()==ID_integer))
    {
      expr=exprt(ID_constant, dest_type);
      expr.set(ID_value, ID_NULL);
      return; // ok
    }
  
    if(src_type.id()==ID_pointer ||
       src_type.id()==ID_array)
    {
      // we are quite generous about pointers
      
      const typet &src_sub=ns.follow(src_type.subtype());
      const typet &dest_sub=ns.follow(dest_type.subtype());

      if(is_void_pointer(src_type) ||
         is_void_pointer(dest_type))
      {
        // from/to void is always good
      }
      else if(src_sub.id()==ID_code &&
              dest_sub.id()==ID_code)
      {
        // very generous:
        // between any two function pointers it's ok
      }
      else if(base_type_eq(src_type.subtype(), dest_type.subtype(), ns))
      {
        // ok
      }
      else if((is_number(src_sub) || src_sub.id()==ID_c_enum) &&
              (is_number(dest_sub) || dest_sub.id()==ID_c_enum))
      {
        // Also generous: between any to scalar types it's ok.
        // We should probably check the size.
      }
      else
        warnings.push_back("incompatible pointer types");

      // check qualifiers

      /*
      if(src_type.subtype().get_bool(ID_C_constant) &&
         !dest_type.subtype().get_bool(ID_C_constant))
        warnings.push_back("disregarding const");
      */

      if(src_type.subtype().get_bool(ID_C_volatile) &&
         !dest_type.subtype().get_bool(ID_C_volatile))
        warnings.push_back("disregarding volatile");

      if(src_type==dest_type)
      {
        expr.type()=src_type; // because of qualifiers
      }
      else
        do_typecast(expr, dest_type);

      return; // ok
    }
  }
  
  if(check_c_implicit_typecast(src_type, dest_type))
    errors.push_back("implicit conversion not permitted");
  else if(src_type!=dest_type)
    do_typecast(expr, dest_type);
}
示例#3
0
bool check_c_implicit_typecast(
  const typet &src_type,
  const typet &dest_type)
{
  // check qualifiers  

  if(src_type.id()==ID_pointer && dest_type.id()==ID_pointer &&
     src_type.subtype().get_bool(ID_C_constant) &&
     !dest_type.subtype().get_bool(ID_C_constant))
    return true;

  if(src_type==dest_type) return false;
  
  const irep_idt &src_type_id=src_type.id();

  if(src_type_id==ID_c_bit_field)
    return check_c_implicit_typecast(src_type.subtype(), dest_type);

  if(dest_type.id()==ID_c_bit_field)
    return check_c_implicit_typecast(src_type, dest_type.subtype());

  if(src_type_id==ID_natural)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_integer)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_pointer) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_real)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_rational)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_complex) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_bool)
  {
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_pointer) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_c_enum) return false;
    if(dest_type.id()==ID_c_enum_tag) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_unsignedbv ||
          src_type_id==ID_signedbv ||
          src_type_id==ID_c_enum ||
          src_type_id==ID_c_enum_tag ||
          src_type_id==ID_incomplete_c_enum ||
          src_type_id==ID_c_bool)
  {
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_rational) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_pointer) return false;
    if(dest_type.id()==ID_c_enum) return false;
    if(dest_type.id()==ID_c_enum_tag) return false;
    if(dest_type.id()==ID_incomplete_c_enum) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_floatbv ||
          src_type_id==ID_fixedbv)
  {
    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_integer) return false;
    if(dest_type.id()==ID_real) return false;
    if(dest_type.id()==ID_rational) return false;
    if(dest_type.id()==ID_signedbv) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_floatbv) return false;
    if(dest_type.id()==ID_fixedbv) return false;
    if(dest_type.id()==ID_complex) return false;
  }
  else if(src_type_id==ID_complex)
  {
    if(dest_type.id()==ID_complex)
      return check_c_implicit_typecast(src_type.subtype(), dest_type.subtype());
    else
    {
      // 6.3.1.7, par 2:

      // When a value of complex type is converted to a real type, the
      // imaginary part of the complex value is discarded and the value of the
      // real part is converted according to the conversion rules for the
      // corresponding real type.
      
      return check_c_implicit_typecast(src_type.subtype(), dest_type);
    }
  }
  else if(src_type_id==ID_array ||
          src_type_id==ID_pointer)
  {
    if(dest_type.id()==ID_pointer)
    {
      const irept &dest_subtype=dest_type.subtype();
      const irept &src_subtype =src_type.subtype();

      if(src_subtype==dest_subtype)
        return false;
      else if(is_void_pointer(src_type) || // from void to anything
              is_void_pointer(dest_type))  // to void from anything
        return false;
    }
    
    if(dest_type.id()==ID_array &&
       src_type.subtype()==dest_type.subtype()) return false;

    if(dest_type.id()==ID_bool) return false;
    if(dest_type.id()==ID_c_bool) return false;
    if(dest_type.id()==ID_unsignedbv) return false;
    if(dest_type.id()==ID_signedbv) return false;
  }
  else if(src_type_id==ID_vector)
  {
    if(dest_type.id()==ID_vector)
      return false;
  }
  else if(src_type_id==ID_complex)
  {
    if(dest_type.id()==ID_complex)
    {
      // We convert between complex types if we convert between
      // their component types.
      if(!check_c_implicit_typecast(src_type.subtype(), dest_type.subtype()))
        return false;
    }
  }

  return true;
}