void jsil_typecheckt::typecheck_expr_unary_boolean(exprt &expr) { if(expr.operands().size()!=1) { err_location(expr); error() << "operator `" << expr.id() << "' expects one operand" << eom; throw 0; } make_type_compatible(expr.op0(), bool_typet(), true); expr.type()=bool_typet(); }
exprt ranking_synthesis_qbf_bitwiset::bitwise_chain( const irep_idt &termOp, const exprt &expr) const { unsigned width=safe_width(expr, ns); assert(width>0); if(width==1) { if(expr.type()!=bool_typet()) { typecast_exprt t(typet(ID_bool)); t.op() = expr; return t; } else return expr; } exprt res; exprt e(ID_extractbit, bool_typet()); e.copy_to_operands(expr); res = e; res.copy_to_operands(from_integer(0, typet(ID_natural))); for(unsigned i=1; i<width; i++) { if(termOp==ID_notequal) { exprt t(ID_equal, bool_typet()); t.copy_to_operands(res, e); t.op1().copy_to_operands(from_integer(i, typet(ID_natural))); res=not_exprt(t); } else { exprt t(termOp, bool_typet()); t.copy_to_operands(res, e); t.op1().copy_to_operands(from_integer(i, typet(ID_natural))); res=t; } } return res; }
void counterexample_beautificationt::get_minimization_symbols( const bv_cbmct &bv_cbmc, const symex_target_equationt &equation, const symex_target_equationt::SSA_stepst::const_iterator failed, minimization_symbolst &minimization_symbols) { // remove the ones that are assigned under false guards for(symex_target_equationt::SSA_stepst::const_iterator it=equation.SSA_steps.begin(); it!=equation.SSA_steps.end(); it++) { if(it->is_assignment() && it->assignment_type==symex_targett::STATE) { if(!bv_cbmc.prop.l_get(it->guard_literal).is_false()) if(it->original_lhs_object.type()!=bool_typet()) minimization_symbols.insert(it->ssa_lhs); } // reached failed assertion? if(it==failed) break; } }
void transition_refinert::constrain_goto_transition( abstract_transition_relationt &abstract_transition_relation, const exprt &condition, bool negated) { if(abstract_transition_relation.constraints.size()==0) { exprt schoose("bp_schoose", bool_typet()); schoose.copy_to_operands(false_exprt(), false_exprt()); abstract_transition_relation.constraints.push_back(schoose); } // we are only maintaining ONE constraint here assert(abstract_transition_relation.constraints.size()==1); exprt &schoose= abstract_transition_relation.constraints.front(); exprt &constraint=negated?(schoose.op1()):(schoose.op0()); if(constraint.is_false()) { constraint.id(ID_or); constraint.copy_to_operands(false_exprt()); } constraint.copy_to_operands(condition); }
reachability_treet::reachability_treet( const goto_functionst &goto_functions, const namespacet &ns, optionst &opts, std::shared_ptr<symex_targett> target, contextt &context, message_handlert &_message_handler) : goto_functions(goto_functions), permanent_context(context), ns(ns), options(opts), message_handler(_message_handler) { // Put a few useful symbols in the symbol table. symbolt sym; sym.type = bool_typet(); sym.name = "execution_statet::\\guard_exec"; sym.base_name = "execution_statet::\\guard_exec"; context.move(sym); CS_bound = atoi(options.get_option("context-bound").c_str()); TS_slice = atoi(options.get_option("time-slice").c_str()); state_hashing = options.get_bool_option("state-hashing"); directed_interleavings = options.get_bool_option("direct-interleavings"); interactive_ileaves = options.get_bool_option("interactive-ileaves"); round_robin = options.get_bool_option("round-robin"); schedule = options.get_bool_option("schedule"); if (options.get_bool_option("no-por") || options.get_bool_option("control-flow-test")) por = false; else por = true; target_template = target; }
void cpp_typecheckt::convert(cpp_static_assertt &cpp_static_assert) { typecheck_expr(cpp_static_assert.op0()); typecheck_expr(cpp_static_assert.op1()); cpp_static_assert.op0().make_typecast(bool_typet()); make_constant(cpp_static_assert.op0()); if(cpp_static_assert.op0().is_true()) { // ok } else if(cpp_static_assert.op0().is_false()) { // failed err_location(cpp_static_assert); str << "static assertion failed: "; throw 0; } else { // not true or false err_location(cpp_static_assert); str << "static assertion is not constant"; throw 0; } }
void acceleratet::set_dirty_vars(path_acceleratort &accelerator) { for(std::set<exprt>::iterator it=accelerator.dirty_vars.begin(); it!=accelerator.dirty_vars.end(); ++it) { expr_mapt::iterator jt=dirty_vars_map.find(*it); exprt dirty_var; if(jt==dirty_vars_map.end()) { scratch_programt scratch(symbol_table); symbolt new_sym=utils.fresh_symbol("accelerate::dirty", bool_typet()); dirty_var=new_sym.symbol_expr(); dirty_vars_map[*it]=dirty_var; } else { dirty_var=jt->second; } #ifdef DEBUG std::cout << "Setting dirty flag " << expr2c(dirty_var, ns) << " for " << expr2c(*it, ns) << '\n'; #endif accelerator.pure_accelerator.add_instruction(ASSIGN)->code = code_assignt(dirty_var, true_exprt()); } }
/* * Insert a looping path (usually an accelerator) into a goto-program, * beginning at loop_header and jumping back to loop_header via back_jump. * Stores the locations at which the looping path was added in inserted_path. * * THIS DESTROYS looping_path!! */ void acceleratet::insert_looping_path( goto_programt::targett &loop_header, goto_programt::targett &back_jump, goto_programt &looping_path, patht &inserted_path) { goto_programt::targett loop_body=loop_header; ++loop_body; goto_programt::targett jump=program.insert_before(loop_body); jump->make_goto(); jump->guard=side_effect_expr_nondett(bool_typet()); jump->targets.push_back(loop_body); program.destructive_insert(loop_body, looping_path); jump=program.insert_before(loop_body); jump->make_goto(); jump->guard=true_exprt(); jump->targets.push_back(back_jump); for(goto_programt::targett t=loop_header; t!=loop_body; ++t) { inserted_path.push_back(path_nodet(t)); } inserted_path.push_back(path_nodet(back_jump)); }
void goto_checkt::mod_by_zero_check( const mod_exprt &expr, const guardt &guard) { if(!enable_div_by_zero_check) return; // add divison by zero subgoal exprt zero=gen_zero(expr.op1().type()); if(zero.is_nil()) throw "no zero of argument type of operator "+expr.id_string(); exprt inequality(ID_notequal, bool_typet()); inequality.copy_to_operands(expr.op1(), zero); add_guarded_claim( inequality, "division by zero", "division-by-zero", expr.find_source_location(), expr, guard); }
void goto_checkt::pointer_overflow_check( const exprt &expr, const guardt &guard) { if(!enable_pointer_overflow_check) return; if(expr.id()==ID_plus || expr.id()==ID_minus) { if(expr.operands().size()==2) { exprt overflow("overflow-"+expr.id_string(), bool_typet()); overflow.operands()=expr.operands(); add_guarded_claim( not_exprt(overflow), "pointer arithmetic overflow on "+expr.id_string(), "overflow", expr.find_source_location(), expr, guard); } } }
bool acceleratet::is_underapproximate(path_acceleratort &accelerator) { for(std::set<exprt>::iterator it=accelerator.dirty_vars.begin(); it!=accelerator.dirty_vars.end(); ++it) { if(it->id()==ID_symbol && it->type() == bool_typet()) { const irep_idt &id=to_symbol_expr(*it).get_identifier(); const symbolt &sym=symbol_table.lookup(id); if(sym.module=="scratch") { continue; } } #ifdef DEBUG std::cout << "Underapproximate variable: " << expr2c(*it, ns) << '\n'; #endif return true; } return false; }
bool ranking_synthesis_seneschalt::write_input_file(const exprt &e) { assert(e.id()=="and" && e.type()==bool_typet()); std::ofstream f("seneschal.input"); exprt e_ext = e; replace_mapt rmap; std::set<irep_idt> inputs, outputs; collect_variables(e_ext, rmap, inputs, outputs); // write variable declarations write_variables(f, inputs, outputs); f << std::endl; // translate constraints if(!write_constraints(f, rmap, e_ext)) return false; f << std::endl; f.close(); return true; }
typet jsil_prim_type() { return jsil_union_typet({ floatbv_typet(), string_typet(), bool_typet() }); }
bool simplify_exprt::simplify_ieee_float_relation(exprt &expr) { assert(expr.id()==ID_ieee_float_equal || expr.id()==ID_ieee_float_notequal); exprt::operandst &operands=expr.operands(); if(expr.type().id()!=ID_bool) return true; if(operands.size()!=2) return true; // types must match if(expr.op0().type()!=expr.op1().type()) return true; if(expr.op0().type().id()!=ID_floatbv) return true; // first see if we compare to a constant if(expr.op0().is_constant() && expr.op1().is_constant()) { ieee_floatt f0(to_constant_expr(expr.op0())); ieee_floatt f1(to_constant_expr(expr.op1())); if(expr.id()==ID_ieee_float_notequal) expr.make_bool(f0.ieee_not_equal(f1)); else if(expr.id()==ID_ieee_float_equal) expr.make_bool(f0.ieee_equal(f1)); else assert(false); return false; } if(expr.op0()==expr.op1()) { // x!=x is the same as saying isnan(op) exprt isnan(ID_isnan, bool_typet()); isnan.copy_to_operands(expr.op0()); if(expr.id()==ID_ieee_float_notequal) { } else if(expr.id()==ID_ieee_float_equal) isnan.make_not(); else assert(false); expr.swap(isnan); return false; } return true; }
void c_typecastt::implicit_typecast_arithmetic( exprt &expr, c_typet c_type) { typet new_type; const typet &expr_type=ns.follow(expr.type()); switch(c_type) { case PTR: if(expr_type.id()==ID_array) { new_type.id(ID_pointer); new_type.subtype()=expr_type.subtype(); break; } return; case BOOL: new_type=bool_typet(); break; case CHAR: assert(false); // should always be promoted to int case UCHAR: assert(false); // should always be promoted to int case SHORT: assert(false); // should always be promoted to int case USHORT: assert(false); // should always be promoted to int case INT: new_type=int_type(); break; case UINT: new_type=uint_type(); break; case LONG: new_type=long_int_type(); break; case ULONG: new_type=long_uint_type(); break; case LONGLONG: new_type=long_long_int_type(); break; case ULONGLONG: new_type=long_long_uint_type(); break; case SINGLE: new_type=float_type(); break; case DOUBLE: new_type=double_type(); break; case LONGDOUBLE: new_type=long_double_type(); break; case RATIONAL: new_type=rational_typet(); break; case REAL: new_type=real_typet(); break; case INTEGER: new_type=integer_typet(); break; case COMPLEX: return; // do nothing default: return; } if(new_type!=expr_type) { if(new_type.id()==ID_pointer && expr_type.id()==ID_array) { exprt index_expr(ID_index, expr_type.subtype()); index_expr.reserve_operands(2); index_expr.move_to_operands(expr); index_expr.copy_to_operands(gen_zero(index_type())); expr=exprt(ID_address_of, new_type); expr.move_to_operands(index_expr); } else do_typecast(expr, new_type); } }
void jsil_typecheckt::typecheck_ifthenelse(code_ifthenelset &code) { exprt &cond=code.cond(); typecheck_expr(cond); make_type_compatible(cond, bool_typet(), true); typecheck_code(to_code(code.then_case())); if(!code.else_case().is_nil()) typecheck_code(to_code(code.else_case())); }
symbol_exprt goto_convertt::exception_flag() { irep_idt id="$exception_flag"; symbol_tablet::symbolst::const_iterator s_it= symbol_table.symbols.find(id); if(s_it==symbol_table.symbols.end()) { symbolt new_symbol; new_symbol.base_name="$exception_flag"; new_symbol.name=id; new_symbol.is_lvalue=true; new_symbol.is_thread_local=true; new_symbol.is_file_local=false; new_symbol.type=bool_typet(); symbol_table.move(new_symbol); } return symbol_exprt(id, bool_typet()); }
std::pair<exprt,exprt> ranking_synthesis_qbf_bitwiset::ite_template() { exprt function; replace_mapt pre_replace_map; unsigned state_size = get_state_size(); unsigned bits=log((double)state_size)/log(2.0) + 1; symbol_exprt const_sym(CONSTANT_COEFFICIENT_ID, unsignedbv_typet(bits)); const_coefficient=coefficient(const_sym); unsigned cnt=0; for(bodyt::variable_mapt::const_iterator it=body.variable_map.begin(); it!=body.variable_map.end(); it++) { if(used_variables.find(it->first)==used_variables.end()) continue; exprt postsym=symbol_exprt(it->first, ns.lookup(it->first).type); exprt presym=symbol_exprt(it->second, ns.lookup(it->second).type); pre_replace_map[postsym] = presym; // save the corresponding pre-var exprt var=postsym; adjust_type(var.type()); unsigned vwidth = safe_width(var, ns); for(unsigned i=0; i<vwidth; i++) { exprt t(ID_extractbit, bool_typet()); t.copy_to_operands(var); t.copy_to_operands(from_integer(i, typet(ID_natural))); if(it==body.variable_map.begin() && i==0) function = t; else { function = if_exprt(equal_exprt(const_coefficient, from_integer(cnt, const_coefficient.type())), t, function); } cnt++; } } exprt pre_function=function; replace_expr(pre_replace_map, pre_function); return std::pair<exprt,exprt>(pre_function, function); }
typet string_abstractiont::build_type(whatt what) { typet type; switch(what) { case IS_ZERO: type=bool_typet(); break; case LENGTH: type=size_type(); break; case SIZE: type=size_type(); break; } return type; }
void jsil_typecheckt::typecheck_exp_binary_equal(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands" << eom; throw 0; } // operands can be of any types expr.type()=bool_typet(); }
void jsil_typecheckt::typecheck_expr_binary_compare(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands" << eom; throw 0; } make_type_compatible(expr.op0(), floatbv_typet(), true); make_type_compatible(expr.op1(), floatbv_typet(), true); expr.type()=bool_typet(); }
void jsil_typecheckt::typecheck_expr_has_field(exprt &expr) { if(expr.operands().size()!=2) { err_location(expr); error() << "operator `" << expr.id() << "' expects two operands" << eom; throw 0; } make_type_compatible(expr.op0(), jsil_object_type(), true); make_type_compatible(expr.op1(), string_typet(), true); expr.type()=bool_typet(); }
void acceleratet::make_overflow_loc( goto_programt::targett loop_header, goto_programt::targett &loop_end, goto_programt::targett &overflow_loc) { symbolt overflow_sym=utils.fresh_symbol("accelerate::overflow", bool_typet()); const exprt &overflow_var=overflow_sym.symbol_expr(); natural_loops_mutablet::natural_loopt &loop = natural_loops.loop_map[loop_header]; overflow_instrumentert instrumenter(program, overflow_var, symbol_table); for(natural_loops_mutablet::natural_loopt::iterator it=loop.begin(); it!=loop.end(); ++it) { overflow_locs[*it]=goto_programt::targetst(); goto_programt::targetst &added=overflow_locs[*it]; instrumenter.add_overflow_checks(*it, added); loop.insert(added.begin(), added.end()); } goto_programt::targett t=program.insert_after(loop_header); t->make_assignment(); t->code=code_assignt(overflow_var, false_exprt()); t->swap(*loop_header); loop.insert(t); overflow_locs[loop_header].push_back(t); goto_programt::instructiont s(SKIP); overflow_loc=program.insert_after(loop_end); *overflow_loc=s; overflow_loc->swap(*loop_end); loop.insert(overflow_loc); goto_programt::instructiont g(GOTO); g.guard=not_exprt(overflow_var); g.targets.push_back(overflow_loc); goto_programt::targett t2=program.insert_after(loop_end); *t2=g; t2->swap(*loop_end); overflow_locs[overflow_loc].push_back(t2); loop.insert(t2); goto_programt::targett tmp=overflow_loc; overflow_loc=loop_end; loop_end=tmp; }
/// add axioms corresponding to the String.equalsIgnoreCase java function /// \par parameters: function application with two string arguments /// \return a Boolean expression exprt string_constraint_generatort::add_axioms_for_equals_ignore_case( const function_application_exprt &f) { assert(f.type()==bool_typet() || f.type().id()==ID_c_bool); symbol_exprt eq=fresh_boolean("equal_ignore_case"); typecast_exprt tc_eq(eq, f.type()); string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]); typet char_type=to_refined_string_type(s1.type()).get_char_type(); exprt char_a=constant_char('a', char_type); exprt char_A=constant_char('A', char_type); exprt char_Z=constant_char('Z', char_type); typet index_type=s1.length().type(); // We add axioms: // a1 : eq => |s1|=|s2| // a2 : forall qvar, 0<=qvar<|s1|, // eq => char_equal_ignore_case(s1[qvar],s2[qvar]); // a3 : !eq => |s1|!=s2 || (0 <=witness<|s1| &&!char_equal_ignore_case) implies_exprt a1(eq, s1.axiom_for_has_same_length_as(s2)); axioms.push_back(a1); symbol_exprt qvar=fresh_univ_index("QA_equal_ignore_case", index_type); exprt constr2=character_equals_ignore_case( s1[qvar], s2[qvar], char_a, char_A, char_Z); string_constraintt a2(qvar, s1.length(), eq, constr2); axioms.push_back(a2); symbol_exprt witness=fresh_exist_index( "witness_unequal_ignore_case", index_type); exprt zero=from_integer(0, witness.type()); and_exprt bound_witness( binary_relation_exprt(witness, ID_lt, s1.length()), binary_relation_exprt(witness, ID_ge, zero)); exprt witness_eq=character_equals_ignore_case( s1[witness], s2[witness], char_a, char_A, char_Z); not_exprt witness_diff(witness_eq); implies_exprt a3( not_exprt(eq), or_exprt( notequal_exprt(s1.length(), s2.length()), and_exprt(bound_witness, witness_diff))); axioms.push_back(a3); return tc_eq; }
void goto_checkt::add_guarded_claim( const exprt &_expr, const std::string &comment, const std::string &property_class, const source_locationt &source_location, const exprt &src_expr, const guardt &guard) { exprt expr(_expr); // first try simplifier on it if(enable_simplify) simplify(expr, ns); // throw away trivial properties? if(!retain_trivial && expr.is_true()) return; // add the guard exprt guard_expr=guard.as_expr(); exprt new_expr; if(guard_expr.is_true()) new_expr.swap(expr); else { new_expr=exprt(ID_implies, bool_typet()); new_expr.move_to_operands(guard_expr, expr); } if(assertions.insert(new_expr).second) { goto_program_instruction_typet type= enable_assert_to_assume?ASSUME:ASSERT; goto_programt::targett t=new_code.add_instruction(type); std::string source_expr_string=from_expr(ns, "", src_expr); t->guard.swap(new_expr); t->source_location=source_location; t->source_location.set_comment(comment+" in "+source_expr_string); t->source_location.set_property_class(property_class); } }
void bv_cbmct::convert_waitfor_symbol(const exprt &expr, bvt &bv) { if(expr.operands().size()!=1) throw "waitfor_symbol expected to have one operand"; exprt result; const exprt &bound=expr.op0(); make_free_bv_expr(expr.type(), result); // constraint: result<=bound exprt rel_expr(ID_le, bool_typet()); rel_expr.copy_to_operands(result, bound); set_to_true(rel_expr); return convert_bitvector(result, bv); }
void goto_checkt::pointer_rel_check(const exprt &expr, const guardt &guard) { if (expr.operands().size() != 2) throw expr.id_string() + " takes one argument"; if (expr.op0().type().id() == "pointer" && expr.op1().type().id() == "pointer") { // add same-object subgoal if (!options.get_bool_option("no-pointer-check")) { exprt same_object("same-object", bool_typet()); same_object.copy_to_operands(expr.op0(), expr.op1()); add_guarded_claim(same_object, "same object violation", "pointer", expr.find_location(), guard); } } }
void goto_checkt::add_guarded_claim(const exprt &_expr, const std::string &comment, const std::string &property, const locationt &location, const guardt &guard) { bool all_claims = options.get_bool_option("all-claims"); exprt expr(_expr); // first try simplifier on it if (!options.get_bool_option("no-simplify")) { expr2tc tmpexpr; migrate_expr(expr, tmpexpr); base_type(tmpexpr, ns); expr = migrate_expr_back(tmpexpr); simplify(expr); } if (!all_claims && expr.is_true()) return; // add the guard exprt guard_expr = migrate_expr_back(guard.as_expr()); exprt new_expr; if (guard_expr.is_true()) new_expr.swap(expr); else { new_expr = exprt("=>", bool_typet()); new_expr.move_to_operands(guard_expr, expr); } if (assertions.insert(new_expr).second) { goto_programt::targett t = new_code.add_instruction(ASSERT); migrate_expr(new_expr, t->guard); t->location = location; t->location.comment(comment); t->location.property(property); } }
void goto_checkt::div_by_zero_check(const exprt &expr, const guardt &guard) { if (options.get_bool_option("no-div-by-zero-check")) return; if (expr.operands().size() != 2) throw expr.id_string() + " takes two arguments"; // add divison by zero subgoal exprt zero = gen_zero(expr.op1().type()); if (zero.is_nil()) throw "no zero of argument type of operator " + expr.id_string(); exprt inequality("notequal", bool_typet()); inequality.copy_to_operands(expr.op1(), zero); add_guarded_claim(inequality, "division by zero", "division-by-zero", expr.find_location(), guard); }
void gen_binary(exprt &expr, const irep_idt &id, bool default_value) { if(expr.operands().size()==0) { if(default_value) expr.make_true(); else expr.make_false(); } else if(expr.operands().size()==1) { exprt tmp; tmp.swap(expr.op0()); expr.swap(tmp); } else { expr.id(id); expr.type()=bool_typet(); } }