c_typecastt::c_typet c_typecastt::minimum_promotion( const typet &type) const { c_typet c_type=get_c_type(type); // 6.3.1.1, par 2 // "If an int can represent all values of the original type, the // value is converted to an int; otherwise, it is converted to // an unsigned int." c_typet max_type=std::max(c_type, INT); // minimum promotion // The second case can arise if we promote any unsigned type // that is as large as unsigned int. if(config.ansi_c.short_int_width==config.ansi_c.int_width && max_type==USHORT) max_type=UINT; else if(config.ansi_c.char_width==config.ansi_c.int_width && max_type==UCHAR) max_type=UINT; else max_type=std::max(max_type, INT); if(max_type==UINT && type.id()==ID_c_bit_field && to_c_bit_field_type(type).get_width()<config.ansi_c.int_width) max_type=INT; return max_type; }
void c_typecastt::implicit_typecast_arithmetic( exprt &expr1, exprt &expr2) { const typet &type1=ns.follow(expr1.type()); const typet &type2=ns.follow(expr2.type()); c_typet c_type1=get_c_type(type1), c_type2=get_c_type(type2); c_typet max_type=std::max(c_type1, c_type2); // "If an int can represent all values of the original type, the // value is converted to an int; otherwise, it is converted to // an unsigned int." // The second case can arise if we promote any unsigned type // that is as large as unsigned int. if(config.ansi_c.short_int_width==config.ansi_c.int_width && max_type==USHORT) max_type=UINT; else if(config.ansi_c.char_width==config.ansi_c.int_width && max_type==UCHAR) max_type=UINT; else max_type=std::max(max_type, INT); if(max_type==LARGE_SIGNED_INT || max_type==LARGE_UNSIGNED_INT) { // get the biggest width of both unsigned width1=type1.get_int(ID_width); unsigned width2=type2.get_int(ID_width); // produce type typet result_type; if(width1==width2) { if(max_type==LARGE_SIGNED_INT) result_type=signedbv_typet(width1); else result_type=unsignedbv_typet(width1); } else if(width1>width2) result_type=type1; else // width1<width2 result_type=type2; do_typecast(expr1, result_type); do_typecast(expr2, result_type); return; } else if(max_type==COMPLEX) { if(c_type1==COMPLEX && c_type2==COMPLEX) { // promote to the one with bigger subtype if(get_c_type(type1.subtype())>get_c_type(type2.subtype())) do_typecast(expr2, type1); else do_typecast(expr1, type2); } else if(c_type1==COMPLEX) { assert(c_type1==COMPLEX && c_type2!=COMPLEX); do_typecast(expr2, type1.subtype()); do_typecast(expr2, type1); } else { assert(c_type1!=COMPLEX && c_type2==COMPLEX); do_typecast(expr1, type2.subtype()); do_typecast(expr1, type2); } return; } implicit_typecast_arithmetic(expr1, max_type); implicit_typecast_arithmetic(expr2, max_type); if(max_type==PTR) { if(c_type1==VOIDPTR) do_typecast(expr1, expr2.type()); if(c_type2==VOIDPTR) do_typecast(expr2, expr1.type()); } }
void c_typecastt::implicit_typecast_arithmetic(exprt &expr) { c_typet c_type=get_c_type(expr.type()); c_type=std::max(c_type, INT); // minimum promotion implicit_typecast_arithmetic(expr, c_type); }
c_typecastt::c_typet c_typecastt::get_c_type( const typet &type) { unsigned width=type.get_int(ID_width); if(type.id()==ID_signedbv) { if(width<=config.ansi_c.char_width) return CHAR; else if(width<=config.ansi_c.short_int_width) return SHORT; else if(width<=config.ansi_c.int_width) return INT; else if(width<=config.ansi_c.long_int_width) return LONG; else if(width<=config.ansi_c.long_long_int_width) return LONGLONG; else return LARGE_SIGNED_INT; } else if(type.id()==ID_unsignedbv) { if(type.get(ID_C_c_type)==ID_bool) return BOOL; if(width<=config.ansi_c.char_width) return UCHAR; else if(width<=config.ansi_c.short_int_width) return USHORT; else if(width<=config.ansi_c.int_width) return UINT; else if(width<=config.ansi_c.long_int_width) return ULONG; else if(width<=config.ansi_c.long_long_int_width) return ULONGLONG; else return LARGE_UNSIGNED_INT; } else if(type.id()==ID_bool) return BOOL; else if(type.id()==ID_floatbv || type.id()==ID_fixedbv) { if(width<=config.ansi_c.single_width) return SINGLE; else if(width<=config.ansi_c.double_width) return DOUBLE; else if(width<=config.ansi_c.long_double_width) return LONGDOUBLE; } else if(type.id()==ID_pointer) { if(type.subtype().id()==ID_empty) return VOIDPTR; else return PTR; } else if(type.id()==ID_array) { return PTR; } else if(type.id()==ID_c_enum || type.id()==ID_incomplete_c_enum) { return INT; } else if(type.id()==ID_symbol) return get_c_type(ns.follow(type)); else if(type.id()==ID_rational) return RATIONAL; else if(type.id()==ID_real) return REAL; else if(type.id()==ID_complex) return COMPLEX; return OTHER; }
void c_typecastt::implicit_typecast_arithmetic( exprt &expr1, exprt &expr2) { const typet &type1=ns.follow(expr1.type()); const typet &type2=ns.follow(expr2.type()); c_typet c_type1=minimum_promotion(type1), c_type2=minimum_promotion(type2); c_typet max_type=std::max(c_type1, c_type2); if(max_type==LARGE_SIGNED_INT || max_type==LARGE_UNSIGNED_INT) { // get the biggest width of both unsigned width1=type1.get_int(ID_width); unsigned width2=type2.get_int(ID_width); // produce type typet result_type; if(width1==width2) { if(max_type==LARGE_SIGNED_INT) result_type=signedbv_typet(width1); else result_type=unsignedbv_typet(width1); } else if(width1>width2) result_type=type1; else // width1<width2 result_type=type2; do_typecast(expr1, result_type); do_typecast(expr2, result_type); return; } else if(max_type==COMPLEX) { if(c_type1==COMPLEX && c_type2==COMPLEX) { // promote to the one with bigger subtype if(get_c_type(type1.subtype())>get_c_type(type2.subtype())) do_typecast(expr2, type1); else do_typecast(expr1, type2); } else if(c_type1==COMPLEX) { assert(c_type1==COMPLEX && c_type2!=COMPLEX); do_typecast(expr2, type1.subtype()); do_typecast(expr2, type1); } else { assert(c_type1!=COMPLEX && c_type2==COMPLEX); do_typecast(expr1, type2.subtype()); do_typecast(expr1, type2); } return; } else if(max_type==SINGLE || max_type==DOUBLE || max_type==LONGDOUBLE || max_type==FLOAT128) { // Special-case optimisation: // If we have two non-standard sized floats, don't do implicit type // promotion if we can possibly avoid it. if(type1==type2) return; } implicit_typecast_arithmetic(expr1, max_type); implicit_typecast_arithmetic(expr2, max_type); if(max_type==PTR) { if(c_type1==VOIDPTR) do_typecast(expr1, expr2.type()); if(c_type2==VOIDPTR) do_typecast(expr2, expr1.type()); } }