bool clang_c_convertert::convert_integer_literal( const clang::IntegerLiteral &integer_literal, exprt &dest) { typet type; if(get_type(integer_literal.getType(), type)) return true; assert(type.is_unsignedbv() || type.is_signedbv()); llvm::APInt val = integer_literal.getValue(); exprt the_val; if (type.is_unsignedbv()) { the_val = constant_exprt( integer2binary(val.getZExtValue(), bv_width(type)), integer2string(val.getZExtValue()), type); } else { the_val = constant_exprt( integer2binary(val.getSExtValue(), bv_width(type)), integer2string(val.getSExtValue()), type); } dest.swap(the_val); return false; }
exprt from_integer(const mp_integer &int_value, const typet &type) { exprt expr; expr.clear(); expr.type() = type; expr.id("constant"); const irep_idt &type_id = type.id(); if(type_id == "unsignedbv" || type_id == "signedbv") { expr.value(integer2binary(int_value, bv_width(type))); return expr; } if(type_id == "bool") { if(int_value == 0) { expr.make_false(); return expr; } if(int_value == 1) { expr.make_true(); return expr; } } expr.make_nil(); return expr; }
constant_exprt fixedbvt::to_expr() const { fixedbv_typet type; type.set_width(spec.width); type.set_integer_bits(spec.integer_bits); constant_exprt expr(type); assert(spec.width!=0); expr.set_value(integer2binary(v, spec.width)); return expr; }
bvt bv_utilst::build_constant(const mp_integer &n, std::size_t width) { std::string n_str=integer2binary(n, width); bvt result; result.resize(width); assert(n_str.size()==width); for(std::size_t i=0; i<width; i++) result[i]=const_literal(n_str[width-i-1]=='1'); return result; }
std::string smt1_dect::mathsat_value(const std::string &src) { std::size_t pos=src.find('['); if(std::string(src, 0, 2)=="bv" && pos!=std::string::npos && src[src.size()-1]==']') { unsigned width=safe_string2unsigned(std::string(src, pos+1, src.size()-pos-2)); mp_integer i=string2integer(std::string(src, 2, pos-2)); return integer2binary(i, width); } return ""; }
bool clang_c_convertert::convert_character_literal( const clang::CharacterLiteral &char_literal, exprt &dest) { typet type; if(get_type(char_literal.getType(), type)) return true; dest = constant_exprt( integer2binary(char_literal.getValue(), bv_width(type)), integer2string(char_literal.getValue()), type); return false; }
decision_proceduret::resultt smt1_dect::read_result_cvc3(std::istream &in) { std::string line; decision_proceduret::resultt res = D_ERROR; smt1_prop.reset_assignment(); typedef hash_map_cont<std::string, std::string, string_hash> valuest; valuest values; while(str_getline(in, line)) { if(line=="sat") res = D_SATISFIABLE; else if(line=="unsat") res = D_UNSATISFIABLE; else if(line.find("Current scope level")!=std::string::npos || line.find("Variable Assignment")!=std::string::npos) ; //ignore else { assert(line.substr(0,13)==" :assumption"); std::size_t pos=line.find('('); if(pos!=std::string::npos) { std::string var; std::string val; if(line[pos+1]=='=') { std::string ops = line.substr(pos+3, line.length()-pos-4); std::size_t blank=ops.find(' '); var = ops.substr(0, blank); val = ops.substr(blank+1, ops.length()-blank); if((var.length()>=4 && var.substr(0,4)=="cvc3") || (val.length()>=4 && val.substr(0,4)=="cvc3") || var==val) continue; else if((var.substr(0,9)=="array_of'") || (var.substr(0,2)=="bv" && val.substr(0,2)!="bv")) { std::string t=var; var=val; val=t; } } else if(line.substr(pos+1,3)=="not") { var = line.substr(pos+5, line.length()-pos-6); val = "false"; } else { var = line.substr(pos+1, line.length()-pos-2); assert(var.find(' ')==std::string::npos); val = "true"; } values[var]=val; } } } for(identifier_mapt::iterator it=identifier_map.begin(); it!=identifier_map.end(); it++) { it->second.value.make_nil(); std::string conv_id=convert_identifier(it->first); std::string value=values[conv_id]; if(value=="") continue; if(value.substr(0,2)=="bv") { std::string v=value.substr(2, value.find('[')-2); size_t p = value.find('[')+1; std::string w=value.substr(p, value.find(']')-p); std::string binary=integer2binary(string2integer(v,10), string2integer(w,10).to_ulong()); set_value(it->second, "", binary); } else if(value=="false") it->second.value.make_false(); else if(value=="true") it->second.value.make_true(); else if(value.substr(0,8)=="array_of") { // We assume that array_of has only concrete arguments... irep_idt id(value); array_of_mapt::const_iterator fit=array_of_map.begin(); while(fit!=array_of_map.end() && fit->second!=id) fit++; if(fit!=array_of_map.end()) it->second.value = fit->first; } else set_value(it->second, "", value); } // Booleans for(unsigned v=0; v<smt1_prop.no_variables(); v++) { std::string value=values["B"+i2string(v)]; if(value=="") continue; smt1_prop.set_assignment(literalt(v, false), value=="true"); } return res; }
bool smt1_dect::string_to_expr_z3( const typet &type, const std::string &value, exprt &e) const { if(value.substr(0,2)=="bv") { std::string v=value.substr(2, value.find('[')-2); size_t p = value.find('[')+1; std::string w=value.substr(p, value.find(']')-p); std::string binary=integer2binary(string2integer(v,10), string2integer(w,10).to_ulong()); if(type.id()==ID_struct) { e=binary2struct(to_struct_type(type), binary); } else if(type.id()==ID_union) { e=binary2union(to_union_type(type), binary); } else { constant_exprt c(type); c.set_value(binary); e=c; } return true; } else if(value.substr(0,6)=="(const") // const arrays { std::string av = value.substr(7, value.length()-8); exprt ae; if(!string_to_expr_z3(type.subtype(), av, ae)) return false; array_of_exprt ao; ao.type() = typet("array"); ao.type().subtype()=ae.type(); ao.what() = ae; e = ao; return true; } else if(value.substr(0,6)=="(store") { size_t p1=value.rfind(' ')+1; size_t p2=value.rfind(' ', p1-2)+1; assert(p1!=std::string::npos && p2!=std::string::npos); std::string elem = value.substr(p1, value.size()-p1-1); std::string inx = value.substr(p2, p1-p2-1); std::string array = value.substr(7, p2-8); exprt old; if(!string_to_expr_z3(type, array, old)) return false; exprt where; if(!string_to_expr_z3(array_index_type(), inx, where)) return false; exprt new_val; if(!string_to_expr_z3(type.subtype(), elem, new_val)) return false; e = with_exprt(old, where, new_val); return true; } else if(value=="false") { e = false_exprt(); return true; } else if(value=="true") { e = true_exprt(); return true; } else if(value.substr(0,8)=="array_of") { // We assume that array_of has only concrete arguments... irep_idt id(value); array_of_mapt::const_iterator fit=array_of_map.begin(); while(fit!=array_of_map.end() && fit->second!=id) fit++; if(fit==array_of_map.end()) return false; e = fit->first; return true; } else if(type.id()==ID_rational) { constant_exprt result; result.type()=rational_typet(); if(value.substr(0,4)=="val!") result.set_value(value.substr(4)); else result.set_value(value); e = result; return true; } return false; }
void bv_refinementt::check_SAT(approximationt &a) { // get values get_values(a); // see if the satisfying assignment is spurious in any way const typet &type=ns.follow(a.expr.type()); if(type.id()==ID_floatbv) { // these are all trinary assert(a.expr.operands().size()==3); if(a.over_state==MAX_STATE) return; ieee_float_spect spec(to_floatbv_type(type)); ieee_floatt o0(spec), o1(spec); o0.unpack(a.op0_value); o1.unpack(a.op1_value); ieee_floatt result=o0; o0.rounding_mode=RM; o1.rounding_mode=RM; result.rounding_mode=RM; if(a.expr.id()==ID_floatbv_plus) result+=o1; else if(a.expr.id()==ID_floatbv_minus) result-=o1; else if(a.expr.id()==ID_floatbv_mult) result*=o1; else if(a.expr.id()==ID_floatbv_div) result/=o1; else assert(false); if(result.pack()==a.result_value) // ok return; #ifdef DEBUG ieee_floatt rr(spec); rr.unpack(a.result_value); std::cout << "S1: " << o0 << " " << a.expr.id() << " " << o1 << " != " << rr << std::endl; std::cout << "S2: " << integer2binary(a.op0_value, spec.width()) << " " << a.expr.id() << " " << integer2binary(a.op1_value, spec.width()) << "!=" << integer2binary(a.result_value, spec.width()) << std::endl; std::cout << "S3: " << integer2binary(a.op0_value, spec.width()) << " " << a.expr.id() << " " << integer2binary(a.op1_value, spec.width()) << "==" << integer2binary(result.pack(), spec.width()) << std::endl; #endif //if(a.over_state==1) { std::cout << "DISAGREEMENT!\n"; exit(1); } if(a.over_state<max_node_refinement) { bvt r; float_utilst float_utils(prop); float_utils.spec=spec; float_utils.rounding_mode_bits.set(RM); literalt op0_equal= bv_utils.equal(a.op0_bv, float_utils.build_constant(o0)); literalt op1_equal= bv_utils.equal(a.op1_bv, float_utils.build_constant(o1)); literalt result_equal= bv_utils.equal(a.result_bv, float_utils.build_constant(result)); literalt op0_and_op1_equal= prop.land(op0_equal, op1_equal); prop.l_set_to_true( prop.limplies(op0_and_op1_equal, result_equal)); } else { // give up // remove any previous over-approximation a.over_assumptions.clear(); a.over_state=MAX_STATE; bvt r; float_utilst float_utils(prop); float_utils.spec=spec; float_utils.rounding_mode_bits.set(RM); bvt op0=a.op0_bv, op1=a.op1_bv, res=a.result_bv; if(a.expr.id()==ID_floatbv_plus) r=float_utils.add(op0, op1); else if(a.expr.id()==ID_floatbv_minus) r=float_utils.sub(op0, op1); else if(a.expr.id()==ID_floatbv_mult) r=float_utils.mul(op0, op1); else if(a.expr.id()==ID_floatbv_div) r=float_utils.div(op0, op1); else assert(0); assert(r.size()==res.size()); bv_utils.set_equal(r, res); } } else if(type.id()==ID_signedbv || type.id()==ID_unsignedbv) { // these are all binary assert(a.expr.operands().size()==2); // already full interpretation? if(a.over_state>0) return; bv_spect spec(type); bv_arithmetict o0(spec), o1(spec); o0.unpack(a.op0_value); o1.unpack(a.op1_value); // division by zero is never spurious if((a.expr.id()==ID_div || a.expr.id()==ID_mod) && o1==0) return; if(a.expr.id()==ID_mult) o0*=o1; else if(a.expr.id()==ID_div) o0/=o1; else if(a.expr.id()==ID_mod) o0%=o1; else assert(false); if(o0.pack()==a.result_value) // ok return; if(a.over_state==0) { // we give up right away and add the full interpretation bvt r; if(a.expr.id()==ID_mult) { r=bv_utils.multiplier( a.op0_bv, a.op1_bv, a.expr.type().id()==ID_signedbv?bv_utilst::SIGNED:bv_utilst::UNSIGNED); } else if(a.expr.id()==ID_div) { r=bv_utils.divider( a.op0_bv, a.op1_bv, a.expr.type().id()==ID_signedbv?bv_utilst::SIGNED:bv_utilst::UNSIGNED); } else if(a.expr.id()==ID_mod) { r=bv_utils.remainder( a.op0_bv, a.op1_bv, a.expr.type().id()==ID_signedbv?bv_utilst::SIGNED:bv_utilst::UNSIGNED); } else assert(0); bv_utils.set_equal(r, a.result_bv); } else assert(0); } else assert(0); status() << "Found spurious `" << a.as_string() << "' (state " << a.over_state << ")" << eom; progress=true; if(a.over_state<MAX_STATE) a.over_state++; }
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; }
constant_exprt ieee_floatt::to_expr() const { constant_exprt result(spec.to_type()); result.set_value(integer2binary(pack(), spec.width())); return result; }
decision_proceduret::resultt smt2_dect::read_result_mathsat(std::istream &in) { std::string line; decision_proceduret::resultt res=D_ERROR; smt2_prop.reset_assignment(); typedef hash_map_cont<std::string, std::string, string_hash> valuest; valuest values; while(str_getline(in, line)) { if(line=="sat") res=D_SATISFIABLE; else if(line=="unsat") res=D_UNSATISFIABLE; else if(line.size()>=2 && line[0]=='(') { // ( (B0 true) ) std::size_t pos1=line.find('(', 1); std::size_t pos2=line.find(' ', pos1); std::size_t pos3=line.find(')', pos2); if(pos1!=std::string::npos && pos2!=std::string::npos && pos3!=std::string::npos) { std::string id=std::string(line, pos1+1, pos2-pos1-1); std::string value=std::string(line, pos2+1, pos3-pos2-1); values[id]=value; } } } for(identifier_mapt::iterator it=identifier_map.begin(); it!=identifier_map.end(); it++) { it->second.value.make_nil(); std::string conv_id=convert_identifier(it->first); std::string value=values[conv_id]; if(value=="") continue; if (value.substr(0, 5) == "(_ bv") { // value is "(_ bvDECIMAL_VALUE SIZE" // convert to binary value = value.substr(5); size_t pos = value.find(' '); std::string v = value.substr(0, pos); std::string w = value.substr(pos+1); value = integer2binary(string2integer(v, 10), string2integer(w, 10).to_ulong()); } set_value(it->second, value); } // Booleans for(unsigned v=0; v<smt2_prop.no_variables(); v++) { std::string value=values["B"+i2string(v)]; if(value=="") continue; smt2_prop.set_assignment(literalt(v, false), value=="true"); } return res; }
exprt ieee_floatt::to_expr() const { exprt result=exprt(ID_constant, spec.to_type()); result.set(ID_value, integer2binary(pack(), spec.width())); return result; }
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; }
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; }
exprt bv_arithmetict::to_expr() const { constant_exprt result(spec.to_type()); result.set_value(integer2binary(value, spec.width)); return result; }
std::string cvc_convt::array_index(unsigned i) { return "0bin"+integer2binary(i, config.ansi_c.int_width); }
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())); } }