void c_typecheck_baset::do_designated_initializer( exprt &result, designatort &designator, const exprt &value, bool force_constant) { assert(!designator.empty()); if(value.id()==ID_designated_initializer) { assert(value.operands().size()==1); designator= make_designator( designator.front().type, static_cast<const exprt &>(value.find(ID_designator))); assert(!designator.empty()); return do_designated_initializer( result, designator, value.op0(), force_constant); } exprt *dest=&result; // first phase: follow given designator for(size_t i=0; i<designator.size(); i++) { size_t index=designator[i].index; const typet &type=designator[i].type; const typet &full_type=follow(type); if(full_type.id()==ID_array || full_type.id()==ID_vector) { if(index>=dest->operands().size()) { if(full_type.id()==ID_array && (to_array_type(full_type).size().is_zero() || to_array_type(full_type).size().is_nil())) { // we are willing to grow an incomplete or zero-sized array exprt zero=zero_initializer(full_type.subtype(), value.source_location(), *this, get_message_handler()); dest->operands().resize(integer2size_t(index)+1, zero); // todo: adjust type! } else { err_location(value); error() << "array index designator " << index << " out of bounds (" << dest->operands().size() << ")" << eom; throw 0; } } dest=&(dest->operands()[integer2size_t(index)]); } else if(full_type.id()==ID_struct) { const struct_typet::componentst &components= to_struct_type(full_type).components(); if(index>=dest->operands().size()) { err_location(value); error() << "structure member designator " << index << " out of bounds (" << dest->operands().size() << ")" << eom; throw 0; } assert(index<components.size()); assert(components[index].type().id()!=ID_code && !components[index].get_is_padding()); dest=&(dest->operands()[index]); } else if(full_type.id()==ID_union) { const union_typet &union_type=to_union_type(full_type); const union_typet::componentst &components= union_type.components(); assert(index<components.size()); const union_typet::componentt &component=union_type.components()[index]; if(dest->id()==ID_union && dest->get(ID_component_name)==component.get_name()) { // Already right union component. We can initialize multiple submembers, // so do not overwrite this. } else { // Note that gcc issues a warning if the union component is switched. // Build a union expression from given component. union_exprt union_expr(type); union_expr.op()=zero_initializer(component.type(), value.source_location(), *this, get_message_handler()); union_expr.add_source_location()=value.source_location(); union_expr.set_component_name(component.get_name()); *dest=union_expr; } dest=&(dest->op0()); } else assert(false); } // second phase: assign value // for this, we may need to go down, adding to the designator while(true) { // see what type we have to initialize const typet &type=designator.back().subtype; const typet &full_type=follow(type); assert(full_type.id()!=ID_symbol); // do we initialize a scalar? if(full_type.id()!=ID_struct && full_type.id()!=ID_union && full_type.id()!=ID_array && full_type.id()!=ID_vector) { // The initializer for a scalar shall be a single expression, // * optionally enclosed in braces. * if(value.id()==ID_initializer_list && value.operands().size()==1) *dest=do_initializer_rec(value.op0(), type, force_constant); else *dest=do_initializer_rec(value, type, force_constant); assert(full_type==follow(dest->type())); return; // done } // union? The component in the zero initializer might // not be the first one. if(full_type.id()==ID_union) { const union_typet &union_type=to_union_type(full_type); const union_typet::componentst &components= union_type.components(); if(!components.empty()) { const union_typet::componentt &component=union_type.components().front(); union_exprt union_expr(type); union_expr.op()=zero_initializer(component.type(), value.source_location(), *this, get_message_handler()); union_expr.add_source_location()=value.source_location(); union_expr.set_component_name(component.get_name()); *dest=union_expr; } } // see what initializer we are given if(value.id()==ID_initializer_list) { *dest=do_initializer_rec(value, type, force_constant); return; // done } else if(value.id()==ID_string_constant) { // We stop for initializers that are string-constants, // which are like arrays. We only do so if we are to // initialize an array of scalars. if(full_type.id()==ID_array && (follow(full_type.subtype()).id()==ID_signedbv || follow(full_type.subtype()).id()==ID_unsignedbv)) { *dest=do_initializer_rec(value, type, force_constant); return; // done } } else if(follow(value.type())==full_type) { // a struct/union/vector can be initialized directly with // an expression of the right type. This doesn't // work with arrays, unfortunately. if(full_type.id()==ID_struct || full_type.id()==ID_union || full_type.id()==ID_vector) { *dest=value; return; // done } } assert(full_type.id()==ID_struct || full_type.id()==ID_union || full_type.id()==ID_array || full_type.id()==ID_vector); // we are initializing a compound type, and enter it! // this may change the type, full_type might not be valid anymore const typet dest_type=full_type; designator_enter(type, designator); if(dest->operands().empty()) { err_location(value); error() << "cannot initialize type `" << to_string(dest_type) << "' using value `" << to_string(value) << "'" << eom; throw 0; } dest=&(dest->op0()); // we run into another loop iteration } }
int goto_fence_inserter_parse_optionst::doit() { if(cmdline.isset("version")) { std::cout << MUSKETEER_VERSION << std::endl; return 0; } if(cmdline.args.size()!=1 && cmdline.args.size()!=2) { help(); return 0; } set_verbosity(); try { register_languages(); goto_functionst goto_functions; get_goto_program(goto_functions); instrument_goto_program(goto_functions); // write new binary? if(cmdline.args.size()==2) { status() << "Writing GOTO program to " << cmdline.args[1] << eom; if(write_goto_binary( cmdline.args[1], symbol_table, goto_functions, get_message_handler())) return 1; else return 0; } // help(); return 0; } catch(const char *e) { error() << e << eom; return 11; } catch(const std::string e) { error() << e << eom; return 11; } catch(int) { return 11; } catch(std::bad_alloc) { error() << "Out of memory" << eom; return 11; } }
bool language_filest::typecheck(contextt &context) { // typecheck interfaces for(filemapt::iterator it=filemap.begin(); it!=filemap.end(); it++) { if(it->second.language->interfaces(context, get_message_handler())) return true; } // build module map unsigned collision_counter=0; for(filemapt::iterator fm_it=filemap.begin(); fm_it!=filemap.end(); fm_it++) { const language_filet::modulest &modules= fm_it->second.modules; for(language_filet::modulest::const_iterator mo_it=modules.begin(); mo_it!=modules.end(); mo_it++) { // these may collide, and then get renamed std::string module_name=*mo_it; while(modulemap.find(module_name)!=modulemap.end()) { module_name=*mo_it+"#"+i2string(collision_counter); collision_counter++; } language_modulet module; module.file=&fm_it->second; module.name=module_name; modulemap.insert( std::pair<std::string, language_modulet>(module.name, module)); } } // typecheck files for(filemapt::iterator it=filemap.begin(); it!=filemap.end(); it++) { if(it->second.modules.empty()) if(it->second.language->typecheck(context, "", get_message_handler())) return true; } // typecheck modules for(modulemapt::iterator it=modulemap.begin(); it!=modulemap.end(); it++) { if(typecheck_module(context, it->second)) return true; } return false; }
bool cbmc_parseoptionst::process_goto_program( const optionst &options, goto_functionst &goto_functions) { try { namespacet ns(context); if(cmdline.isset("string-abstraction")) string_instrumentation( context, get_message_handler(), goto_functions); status("Function Pointer Removal"); remove_function_pointers(ns, goto_functions, cmdline.isset("pointer-check")); status("Partial Inlining"); // do partial inlining goto_partial_inline(goto_functions, ns, ui_message_handler); status("Generic Property Instrumentation"); // add generic checks goto_check(ns, options, goto_functions); if(cmdline.isset("string-abstraction")) { status("String Abstraction"); string_abstraction(context, get_message_handler(), goto_functions); } // add failed symbols // needs to be done before pointer analysis add_failed_symbols(context); if(cmdline.isset("pointer-check") || cmdline.isset("show-value-sets")) { status("Pointer Analysis"); value_set_analysist value_set_analysis(ns); value_set_analysis(goto_functions); // show it? if(cmdline.isset("show-value-sets")) { show_value_sets(get_ui(), goto_functions, value_set_analysis); return true; } status("Adding Pointer Checks"); // add pointer checks pointer_checks( goto_functions, context, options, value_set_analysis); } // recalculate numbers, etc. goto_functions.update(); // add loop ids goto_functions.compute_loop_numbers(); // if we aim to cover, replace // all assertions by false to prevent simplification if(cmdline.isset("cover-assertions")) make_assertions_false(goto_functions); // show it? if(cmdline.isset("show-loops")) { show_loop_numbers(get_ui(), goto_functions); return true; } // show it? if(cmdline.isset("show-goto-functions")) { goto_functions.output(ns, std::cout); return true; } } catch(const char *e) { error(e); return true; } catch(const std::string e) { error(e); return true; } catch(int) { return true; } catch(std::bad_alloc) { error("Out of memory"); return true; } return false; }
exprt summarizer_bw_termt::compute_precondition( local_SSAt &SSA, summaryt &summary, const exprt::operandst &postconditions, incremental_solvert &solver, template_generator_summaryt &template_generator, bool context_sensitive) { exprt postcond=not_exprt(conjunction(postconditions)); // compute backward summary exprt bw_transformer, bw_invariant, bw_precondition; if(!template_generator.out_vars().empty()) { ssa_analyzert analyzer; analyzer.set_message_handler(get_message_handler()); analyzer(solver, SSA, postcond, template_generator); analyzer.get_result(bw_transformer, template_generator.inout_vars()); analyzer.get_result(bw_invariant, template_generator.loop_vars()); analyzer.get_result(bw_precondition, template_generator.out_vars()); // statistics solver_instances+=analyzer.get_number_of_solver_instances(); solver_calls+=analyzer.get_number_of_solver_calls(); } #if 1 // TODO: yet another workaround for ssa_analyzer // not being able to handle empty templates properly else { solver << SSA; solver.new_context(); solver << SSA.get_enabling_exprs(); solver << postcond; exprt result=true_exprt(); if(solver()==decision_proceduret::D_UNSATISFIABLE) result=false_exprt(); solver.pop_context(); bw_transformer=result; bw_invariant=result; bw_precondition=result; } #endif bw_transformer=not_exprt(bw_transformer); bw_invariant=not_exprt(bw_invariant); bw_precondition=not_exprt(bw_precondition); if(context_sensitive && !summary.bw_postcondition.is_true()) { bw_transformer=implies_exprt(summary.bw_postcondition, bw_transformer); bw_invariant=implies_exprt(summary.bw_postcondition, bw_invariant); bw_precondition=implies_exprt(summary.bw_postcondition, bw_precondition); } // join // TODO: should go into summaryt if(summary.bw_transformer.is_nil()) { summary.bw_transformer=bw_transformer; summary.bw_invariant=bw_invariant; summary.bw_precondition=bw_precondition; } else { summary.bw_transformer=or_exprt(summary.bw_transformer, bw_transformer); summary.bw_invariant=or_exprt(summary.bw_invariant, bw_invariant); summary.bw_precondition=or_exprt(summary.bw_precondition, bw_precondition); } return bw_precondition; }
void summarizer_fwt::do_summary(const function_namet &function_name, local_SSAt &SSA, summaryt &summary, exprt cond, bool context_sensitive) { status() << "Computing summary" << eom; // solver incremental_solvert &solver = ssa_db.get_solver(function_name); solver.set_message_handler(get_message_handler()); //analyze ssa_analyzert analyzer; analyzer.set_message_handler(get_message_handler()); template_generator_summaryt template_generator( options,ssa_db,ssa_unwinder.get(function_name)); template_generator.set_message_handler(get_message_handler()); template_generator(solver.next_domain_number(),SSA,true); exprt::operandst conds; conds.reserve(5); conds.push_back(cond); conds.push_back(summary.fw_precondition); conds.push_back(ssa_inliner.get_summaries(SSA)); #ifdef REUSE_INVARIANTS if(summary_db.exists(function_name)) //reuse existing invariants { const exprt &old_inv = summary_db.get(function_name).fw_invariant; exprt inv = ssa_unwinder.get(function_name).rename_invariant(old_inv); conds.push_back(inv); #if 0 std::ostringstream out; out << "(original inv)" << from_expr(SSA.ns,"",old_inv) << "\n"; debug() << out.str() << eom; out << "(renamed inv)" << from_expr(SSA.ns,"",inv)<<"\n"; debug() << out.str() << eom; #endif } #endif cond = conjunction(conds); bool assertions_check = false; //options.get_bool_option("k-induction"); bool assertions_hold = analyzer(solver,SSA,cond,template_generator, assertions_check); if(assertions_hold) { analyzer.get_result(summary.fw_transformer,template_generator.inout_vars()); analyzer.get_result(summary.fw_invariant,template_generator.loop_vars()); #ifdef SHOW_WHOLE_RESULT // to see all the custom template values exprt whole_result; analyzer.get_result(whole_result,template_generator.all_vars()); debug() << "whole result: " << from_expr(SSA.ns,"",whole_result) << eom; #endif if(context_sensitive && !summary.fw_precondition.is_true()) { summary.fw_transformer = implies_exprt(summary.fw_precondition,summary.fw_transformer); summary.fw_invariant = implies_exprt(summary.fw_precondition,summary.fw_invariant); } } else //!assertions_hold { nonpassed_assertions = true; summary.nonpassed_assertions = analyzer.get_nonpassed_assertions(); } solver_instances += analyzer.get_number_of_solver_instances(); solver_calls += analyzer.get_number_of_solver_calls(); }
void cover_goals_extt::assignment() { // check loop head choices in model bool invariants_involved=false; if(spurious_check) { for(exprt::operandst::const_iterator l_it=loophead_selects.begin(); l_it!=loophead_selects.end(); l_it++) { if(solver.get(l_it->op0()).is_true()) { invariants_involved=true; break; } } } if(!invariants_involved || !spurious_check) { std::list<cover_goals_extt::cover_goalt>::const_iterator g_it=goals.begin(); for(goal_mapt::const_iterator it=goal_map.begin(); it!=goal_map.end(); it++, g_it++) { if(property_map[it->first].result==property_checkert::UNKNOWN && solver.l_get(g_it->condition).is_true()) { property_map[it->first].result=property_checkert::FAIL; if(build_error_trace) { ssa_build_goto_tracet build_goto_trace(SSA, solver.get_solver()); build_goto_trace(property_map[it->first].error_trace); if(!all_properties) break; } } } return; } solver.new_context(); // force avoiding paths going through invariants solver << conjunction(loophead_selects); switch(solver()) { case decision_proceduret::D_SATISFIABLE: { std::list<cover_goals_extt::cover_goalt>::const_iterator g_it=goals.begin(); for(goal_mapt::const_iterator it=goal_map.begin(); it!=goal_map.end(); it++, g_it++) { if(property_map[it->first].result==property_checkert::UNKNOWN && solver.l_get(g_it->condition).is_true()) { property_map[it->first].result=property_checkert::FAIL; if(build_error_trace) { ssa_build_goto_tracet build_goto_trace(SSA, solver.get_solver()); build_goto_trace(property_map[it->first].error_trace); #if 0 show_raw_countermodel( it->first, SSA, *solver.solver, debug(), get_message_handler()); #endif if(!all_properties) break; } } } break; } case decision_proceduret::D_UNSATISFIABLE: break; case decision_proceduret::D_ERROR: default: throw "error from decision procedure"; } solver.pop_context(); _iterations++; // statistics }
safety_checkert::resultt bmc_all_propertiest::operator()() { status() << "Passing problem to " << solver.decision_procedure_text() << eom; solver.set_message_handler(get_message_handler()); // stop the time absolute_timet sat_start=current_time(); bmc.do_conversion(); // Collect _all_ goals in `goal_map'. // This maps property IDs to 'goalt' forall_goto_functions(f_it, goto_functions) forall_goto_program_instructions(i_it, f_it->second.body) if(i_it->is_assert()) goal_map[i_it->source_location.get_property_id()]=goalt(*i_it); // get the conditions for these goals from formula // collect all 'instances' of the properties for(symex_target_equationt::SSA_stepst::iterator it=bmc.equation.SSA_steps.begin(); it!=bmc.equation.SSA_steps.end(); it++) { if(it->is_assert()) { irep_idt property_id; if(it->source.pc->is_assert()) property_id=it->source.pc->source_location.get_property_id(); else if(it->source.pc->is_goto()) { // this is likely an unwinding assertion property_id=id2string( it->source.pc->source_location.get_function())+".unwind."+ std::to_string(it->source.pc->loop_number); goal_map[property_id].description=it->comment; } else continue; goal_map[property_id].instances.push_back(it); } } do_before_solving(); cover_goalst cover_goals(solver); cover_goals.set_message_handler(get_message_handler()); cover_goals.register_observer(*this); for(const auto &g : goal_map) { // Our goal is to falsify a property, i.e., we will // add the negation of the property as goal. literalt p=!solver.convert(g.second.as_expr()); cover_goals.add(p); } status() << "Running " << solver.decision_procedure_text() << eom; bool error=false; decision_proceduret::resultt result=cover_goals(); if(result==decision_proceduret::resultt::D_ERROR) { error=true; for(auto &g : goal_map) if(g.second.status==goalt::statust::UNKNOWN) g.second.status=goalt::statust::ERROR; } else { for(auto &g : goal_map) if(g.second.status==goalt::statust::UNKNOWN) g.second.status=goalt::statust::SUCCESS; } // output runtime { absolute_timet sat_stop=current_time(); status() << "Runtime decision procedure: " << (sat_stop-sat_start) << "s" << eom; } // report report(cover_goals); if(error) return safety_checkert::resultt::ERROR; bool safe=(cover_goals.number_covered()==0); if(safe) bmc.report_success(); // legacy, might go away else bmc.report_failure(); // legacy, might go away return safe?safety_checkert::resultt::SAFE:safety_checkert::resultt::UNSAFE; }
get_message_handler())) { return true; } remove_internal_symbols(new_symbol_table); if(linking(symbol_table, new_symbol_table, get_message_handler())) return true; return false; } bool ansi_c_languaget::final(symbol_tablet &symbol_table) { if(ansi_c_entry_point(symbol_table, "main", get_message_handler())) return true; return false; } void ansi_c_languaget::show_parse(std::ostream &out) { parse_tree.output(out); } languaget *new_ansi_c_language() { return new ansi_c_languaget; }
bool get_goto_modelt::operator()(const std::vector<std::string> &files) { if(files.empty()) { error() << "Please provide a program" << eom; return true; } try { std::vector<std::string> binaries, sources; binaries.reserve(files.size()); sources.reserve(files.size()); for(const auto &file : files) { if(is_goto_binary(file)) binaries.push_back(file); else sources.push_back(file); } if(!sources.empty()) { language_filest language_files; language_files.set_message_handler(get_message_handler()); for(const auto &filename : sources) { #ifdef _MSC_VER std::ifstream infile(widen(filename)); #else std::ifstream infile(filename); #endif if(!infile) { error() << "failed to open input file `" << filename << '\'' << eom; return true; } std::pair<language_filest::file_mapt::iterator, bool> result=language_files.file_map.insert( std::pair<std::string, language_filet>(filename, language_filet())); language_filet &lf=result.first->second; lf.filename=filename; lf.language=get_language_from_filename(filename); if(lf.language==NULL) { error("failed to figure out type of file", filename); return true; } languaget &language=*lf.language; language.set_message_handler(get_message_handler()); status() << "Parsing " << filename << eom; if(language.parse(infile, filename)) { error() << "PARSING ERROR" << eom; return true; } lf.get_modules(); } status() << "Converting" << eom; if(language_files.typecheck(symbol_table)) { error() << "CONVERSION ERROR" << eom; return true; } if(binaries.empty()) { if(language_files.final(symbol_table)) { error() << "CONVERSION ERROR" << eom; return true; } } } for(const auto &file : binaries) { status() << "Reading GOTO program from file" << eom; if(read_object_and_link(file, *this, get_message_handler())) return true; } if(!binaries.empty()) config.set_from_symbol_table(symbol_table); status() << "Generating GOTO Program" << eom; goto_convert(symbol_table, goto_functions, get_message_handler()); }
bool ansi_c_languaget::parse( std::istream &instream, const std::string &path) { // store the path parse_path=path; // preprocessing std::ostringstream o_preprocessed; if(preprocess(instream, path, o_preprocessed)) return true; std::istringstream i_preprocessed(o_preprocessed.str()); // parsing std::string code; ansi_c_internal_additions(code); std::istringstream codestr(code); ansi_c_parser.clear(); ansi_c_parser.set_file(ID_built_in); ansi_c_parser.in=&codestr; ansi_c_parser.set_message_handler(get_message_handler()); ansi_c_parser.for_has_scope=config.ansi_c.for_has_scope; ansi_c_parser.cpp98=false; // it's not C++ ansi_c_parser.cpp11=false; // it's not C++ switch(config.ansi_c.mode) { case configt::ansi_ct::flavourt::MODE_CODEWARRIOR_C_CPP: ansi_c_parser.mode=ansi_c_parsert::CW; break; case configt::ansi_ct::flavourt::MODE_VISUAL_STUDIO_C_CPP: ansi_c_parser.mode=ansi_c_parsert::MSC; break; case configt::ansi_ct::flavourt::MODE_ANSI_C_CPP: ansi_c_parser.mode=ansi_c_parsert::ANSI; break; case configt::ansi_ct::flavourt::MODE_GCC_C: case configt::ansi_ct::flavourt::MODE_GCC_CPP: ansi_c_parser.mode=ansi_c_parsert::GCC; break; case configt::ansi_ct::flavourt::MODE_ARM_C_CPP: ansi_c_parser.mode=ansi_c_parsert::ARM; break; default: assert(false); } ansi_c_scanner_init(); bool result=ansi_c_parser.parse(); if(!result) { ansi_c_parser.set_line_no(0); ansi_c_parser.set_file(path); ansi_c_parser.in=&i_preprocessed; ansi_c_scanner_init(); result=ansi_c_parser.parse(); } // save result parse_tree.swap(ansi_c_parser.parse_tree); // save some memory ansi_c_parser.clear(); return result; }
bool cbmc_parse_optionst::process_goto_program( const optionst &options, goto_functionst &goto_functions) { try { namespacet ns(symbol_table); // Remove inline assembler; this needs to happen before // adding the library. remove_asm(symbol_table, goto_functions); // add the library status() << "Adding CPROVER library (" << config.ansi_c.arch << ")" << eom; link_to_library(symbol_table, goto_functions, ui_message_handler); if(cmdline.isset("string-abstraction")) string_instrumentation( symbol_table, get_message_handler(), goto_functions); // remove function pointers status() << "Function Pointer Removal" << eom; remove_function_pointers(symbol_table, goto_functions, cmdline.isset("pointer-check")); // full slice? if(cmdline.isset("full-slice")) { status() << "Performing a full slice" << eom; full_slicer(goto_functions, ns); } // do partial inlining status() << "Partial Inlining" << eom; goto_partial_inline(goto_functions, ns, ui_message_handler); // remove returns, gcc vectors, complex remove_returns(symbol_table, goto_functions); remove_vector(symbol_table, goto_functions); remove_complex(symbol_table, goto_functions); // add generic checks status() << "Generic Property Instrumentation" << eom; goto_check(ns, options, goto_functions); if(cmdline.isset("string-abstraction")) { status() << "String Abstraction" << eom; string_abstraction(symbol_table, get_message_handler(), goto_functions); } // add failed symbols // needs to be done before pointer analysis add_failed_symbols(symbol_table); // recalculate numbers, etc. goto_functions.update(); // add loop ids goto_functions.compute_loop_numbers(); // if we aim to cover assertions, replace // all assertions by false to prevent simplification if(cmdline.isset("cover") && cmdline.get_value("cover")=="assertions") make_assertions_false(goto_functions); // show it? if(cmdline.isset("show-loops")) { show_loop_ids(get_ui(), goto_functions); return true; } // show it? if(cmdline.isset("show-goto-functions")) { goto_functions.output(ns, std::cout); return true; } } catch(const char *e) { error() << e << eom; return true; } catch(const std::string e) { error() << e << eom; return true; } catch(int) { return true; } catch(std::bad_alloc) { error() << "Out of memory" << eom; return true; } return false; }
int cbmc_parse_optionst::get_goto_program( const optionst &options, bmct &bmc, // for get_modules goto_functionst &goto_functions) { if(cmdline.args.empty()) { error() << "Please provide a program to verify" << eom; return 6; } try { if(cmdline.isset("show-parse-tree")) { if(cmdline.args.size()!=1 || is_goto_binary(cmdline.args[0])) { error() << "Please give exactly one source file" << eom; return 6; } std::string filename=cmdline.args[0]; #ifdef _MSC_VER std::ifstream infile(widen(filename).c_str()); #else std::ifstream infile(filename.c_str()); #endif if(!infile) { error() << "failed to open input file `" << filename << "'" << eom; return 6; } languaget *language=get_language_from_filename(filename); if(language==NULL) { error() << "failed to figure out type of file `" << filename << "'" << eom; return 6; } language->set_message_handler(get_message_handler()); status("Parsing", filename); if(language->parse(infile, filename)) { error() << "PARSING ERROR" << eom; return 6; } language->show_parse(std::cout); return 0; } cmdlinet::argst binaries; binaries.reserve(cmdline.args.size()); for(cmdlinet::argst::iterator it=cmdline.args.begin(); it!=cmdline.args.end(); ) // no ++it { if(is_goto_binary(*it)) { binaries.push_back(*it); it=cmdline.args.erase(it); continue; } ++it; } if(!cmdline.args.empty()) { if(parse()) return 6; if(typecheck()) return 6; int get_modules_ret=get_modules(bmc); if(get_modules_ret!=-1) return get_modules_ret; if(binaries.empty() && final()) return 6; // we no longer need any parse trees or language files clear_parse(); } for(cmdlinet::argst::const_iterator it=binaries.begin(); it!=binaries.end(); ++it) { status() << "Reading GOTO program from file " << eom; if(read_object_and_link(*it, symbol_table, goto_functions, *this)) return 6; } if(!binaries.empty()) config.set_from_symbol_table(symbol_table); if(cmdline.isset("show-symbol-table")) { show_symbol_table(); return 0; } if(entry_point(symbol_table, "main", get_message_handler())) return 6; status() << "Generating GOTO Program" << eom; goto_convert(symbol_table, goto_functions, ui_message_handler); if(process_goto_program(options, goto_functions)) return 6; } catch(const char *e) { error() << e << eom; return 6; } catch(const std::string e) { error() << e << eom; return 6; } catch(int) { return 6; } catch(std::bad_alloc) { error() << "Out of memory" << eom; return 6; } return -1; // no error, continue }
void c_typecheck_baset::typecheck_type(typet &type) { // we first convert, and then check { ansi_c_convert_typet ansi_c_convert_type(get_message_handler()); ansi_c_convert_type.read(type); ansi_c_convert_type.write(type); } if(type.id()==ID_already_typechecked) { // need to preserve any qualifiers c_qualifierst c_qualifiers(type); c_qualifiers+=c_qualifierst(type.subtype()); bool packed=type.get_bool(ID_C_packed); exprt alignment=static_cast<const exprt &>(type.find(ID_C_alignment)); type.swap(type.subtype()); c_qualifiers.write(type); if(packed) type.set(ID_C_packed, true); if(alignment.is_not_nil()) type.add(ID_C_alignment, alignment); return; // done } // do we have alignment? if(type.find(ID_C_alignment).is_not_nil()) { exprt &alignment=static_cast<exprt &>(type.add(ID_C_alignment)); if(alignment.id()!=ID_default) { typecheck_expr(alignment); make_constant(alignment); } } if(type.id()==ID_code) typecheck_code_type(to_code_type(type)); else if(type.id()==ID_array) typecheck_array_type(to_array_type(type)); else if(type.id()==ID_pointer) typecheck_type(type.subtype()); else if(type.id()==ID_struct || type.id()==ID_union) typecheck_compound_type(to_struct_union_type(type)); else if(type.id()==ID_c_enum) typecheck_c_enum_type(type); else if(type.id()==ID_c_enum_tag) typecheck_c_enum_tag_type(to_c_enum_tag_type(type)); else if(type.id()==ID_c_bit_field) typecheck_c_bit_field_type(to_c_bit_field_type(type)); else if(type.id()==ID_typeof) typecheck_typeof_type(type); else if(type.id()==ID_symbol) typecheck_symbol_type(type); else if(type.id()==ID_vector) typecheck_vector_type(to_vector_type(type)); else if(type.id()==ID_custom_unsignedbv || type.id()==ID_custom_signedbv || type.id()==ID_custom_floatbv || type.id()==ID_custom_fixedbv) typecheck_custom_type(type); else if(type.id()==ID_gcc_attribute_mode) { // get that mode irep_idt mode=type.get(ID_size); // A list of all modes ist at // http://www.delorie.com/gnu/docs/gcc/gccint_53.html typecheck_type(type.subtype()); typet underlying_type=type.subtype(); // gcc allows this, but clang doesn't; it's a compiler hint only, // but we'll try to interpret it the GCC way if(underlying_type.id()==ID_c_enum_tag) { underlying_type= follow_tag(to_c_enum_tag_type(underlying_type)).subtype(); assert(underlying_type.id()==ID_signedbv || underlying_type.id()==ID_unsignedbv); } if(underlying_type.id()==ID_signedbv || underlying_type.id()==ID_unsignedbv) { bool is_signed=underlying_type.id()==ID_signedbv; typet result; if(mode=="__QI__") // 8 bits result=is_signed?signed_char_type():unsigned_char_type(); else if(mode=="__byte__") // 8 bits result=is_signed?signed_char_type():unsigned_char_type(); else if(mode=="__HI__") // 16 bits result=is_signed?signed_short_int_type():unsigned_short_int_type(); else if(mode=="__SI__") // 32 bits result=is_signed?signed_int_type():unsigned_int_type(); else if(mode=="__word__") // long int, we think result=is_signed?signed_long_int_type():unsigned_long_int_type(); else if(mode=="__pointer__") // we think this is size_t/ssize_t result=is_signed?signed_size_type():size_type(); else if(mode=="__DI__") // 64 bits { if(config.ansi_c.long_int_width==64) result=is_signed?signed_long_int_type():unsigned_long_int_type(); else { assert(config.ansi_c.long_long_int_width==64); result= is_signed?signed_long_long_int_type():unsigned_long_long_int_type(); } } else if(mode=="__TI__") // 128 bits result=is_signed?gcc_signed_int128_type():gcc_unsigned_int128_type(); else if(mode=="__V2SI__") // vector of 2 ints, deprecated by gcc result= vector_typet( is_signed?signed_int_type():unsigned_int_type(), from_integer(2, size_type())); else if(mode=="__V4SI__") // vector of 4 ints, deprecated by gcc result= vector_typet( is_signed?signed_int_type():unsigned_int_type(), from_integer(4, size_type())); else // give up, just use subtype result=type.subtype(); // save the location result.add_source_location()=type.source_location(); if(type.subtype().id()==ID_c_enum_tag) { const irep_idt &tag_name= to_c_enum_tag_type(type.subtype()).get_identifier(); symbol_tablet::symbolst::iterator entry= symbol_table.symbols.find(tag_name); assert(entry!=symbol_table.symbols.end()); entry->second.type.subtype()=result; } type=result; } else if(underlying_type.id()==ID_floatbv) { typet result; if(mode=="__SF__") // 32 bits result=float_type(); else if(mode=="__DF__") // 64 bits result=double_type(); else if(mode=="__TF__") // 128 bits result=gcc_float128_type(); else if(mode=="__V2SF__") // vector of 2 floats, deprecated by gcc result=vector_typet(float_type(), from_integer(2, size_type())); else if(mode=="__V2DF__") // vector of 2 doubles, deprecated by gcc result=vector_typet(double_type(), from_integer(2, size_type())); else if(mode=="__V4SF__") // vector of 4 floats, deprecated by gcc result=vector_typet(float_type(), from_integer(4, size_type())); else if(mode=="__V4DF__") // vector of 4 doubles, deprecated by gcc result=vector_typet(double_type(), from_integer(4, size_type())); else // give up, just use subtype result=type.subtype(); // save the location result.add_source_location()=type.source_location(); type=result; } else if(underlying_type.id()==ID_complex) { // gcc allows this, but clang doesn't -- see enums above typet result; if(mode=="__SC__") // 32 bits result=float_type(); else if(mode=="__DC__") // 64 bits result=double_type(); else if(mode=="__TC__") // 128 bits result=gcc_float128_type(); else // give up, just use subtype result=type.subtype(); // save the location result.add_source_location()=type.source_location(); type=complex_typet(result); } else { error().source_location=type.source_location(); error() << "attribute mode `" << mode << "' applied to inappropriate type `" << to_string(type) << "'" << eom; throw 0; } } // do a mild bit of rule checking if(type.get_bool(ID_C_restricted) && type.id()!=ID_pointer && type.id()!=ID_array) { error().source_location=type.source_location(); error() << "only a pointer can be 'restrict'" << eom; throw 0; } }
exprt c_typecheck_baset::do_initializer_rec( const exprt &value, const typet &type, bool force_constant) { const typet &full_type=follow(type); if(full_type.id()==ID_incomplete_struct) { err_location(value); error() << "type `" << to_string(full_type) << "' is still incomplete -- cannot initialize" << eom; throw 0; } if(value.id()==ID_initializer_list) return do_initializer_list(value, type, force_constant); if(value.id()==ID_array && value.get_bool(ID_C_string_constant) && full_type.id()==ID_array && (full_type.subtype().id()==ID_signedbv || full_type.subtype().id()==ID_unsignedbv) && full_type.subtype().get(ID_width)==value.type().subtype().get(ID_width)) { exprt tmp=value; // adjust char type tmp.type().subtype()=full_type.subtype(); Forall_operands(it, tmp) it->type()=full_type.subtype(); if(full_type.id()==ID_array && to_array_type(full_type).is_complete()) { // check size mp_integer array_size; if(to_integer(to_array_type(full_type).size(), array_size)) { err_location(value); error() << "array size needs to be constant, got " << to_string(to_array_type(full_type).size()) << eom; throw 0; } if(array_size<0) { err_location(value); error() << "array size must not be negative" << eom; throw 0; } if(mp_integer(tmp.operands().size())>array_size) { // cut off long strings. gcc does a warning for this tmp.operands().resize(integer2size_t(array_size)); tmp.type()=type; } else if(mp_integer(tmp.operands().size())<array_size) { // fill up tmp.type()=type; exprt zero=zero_initializer(full_type.subtype(), value.source_location(), *this, get_message_handler()); tmp.operands().resize(integer2size_t(array_size), zero); } } return tmp; } if(value.id()==ID_string_constant && full_type.id()==ID_array && (full_type.subtype().id()==ID_signedbv || full_type.subtype().id()==ID_unsignedbv) && full_type.subtype().get(ID_width)==char_type().get(ID_width)) { // will go away, to be replaced by the above block string_constantt tmp1=to_string_constant(value); // adjust char type tmp1.type().subtype()=full_type.subtype(); exprt tmp2=tmp1.to_array_expr(); if(full_type.id()==ID_array && to_array_type(full_type).is_complete()) { // check size mp_integer array_size; if(to_integer(to_array_type(full_type).size(), array_size)) { err_location(value); error() << "array size needs to be constant, got " << to_string(to_array_type(full_type).size()) << eom; throw 0; } if(array_size<0) { err_location(value); error() << "array size must not be negative" << eom; throw 0; } if(mp_integer(tmp2.operands().size())>array_size) { // cut off long strings. gcc does a warning for this tmp2.operands().resize(integer2size_t(array_size)); tmp2.type()=type; } else if(mp_integer(tmp2.operands().size())<array_size) { // fill up tmp2.type()=type; exprt zero=zero_initializer(full_type.subtype(), value.source_location(), *this, get_message_handler()); tmp2.operands().resize(integer2size_t(array_size), zero); } } return tmp2; } if(full_type.id()==ID_array && to_array_type(full_type).size().is_nil()) { err_location(value); error() << "type `" << to_string(full_type) << "' cannot be initialized with `" << to_string(value) << "'" << eom; throw 0; } if(value.id()==ID_designated_initializer) { err_location(value); error() << "type `" << to_string(full_type) << "' cannot be initialized with designated initializer" << eom; throw 0; } exprt result=value; implicit_typecast(result, type); return result; }
property_checkert::resultt summary_checker_acdlt::operator()( const goto_modelt &goto_model) { const namespacet ns(goto_model.symbol_table); SSA_functions(goto_model, ns); ssa_unwinder.init(false, false); unsigned unwind=options.get_unsigned_int_option("unwind"); if(unwind>0) { status() << "Unwinding" << messaget::eom; ssa_unwinder.init_localunwinders(); ssa_unwinder.unwind_all(unwind); } irep_idt entry_point=goto_model.goto_functions.entry_point(); std::cout << entry_point << std::endl; local_SSAt &SSA=ssa_db.get(entry_point); ssa_local_unwindert &ssa_local_unwinder=ssa_unwinder.get(entry_point); const goto_programt &goto_program=SSA.goto_function.body; for(goto_programt::instructionst::const_iterator i_it=goto_program.instructions.begin(); i_it!=goto_program.instructions.end(); i_it++) { /*if(!i_it->is_assert() || !i_it->is_assume()) continue; */ const source_locationt &location=i_it->source_location; irep_idt property_id=location.get_property_id(); if(i_it->guard.is_true()) { property_map[property_id].result=PASS; continue; } if(property_id=="") // TODO: some properties do not show up in initialize_property_map continue; // get loophead selects exprt::operandst loophead_selects; for(local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin(); n_it!=SSA.nodes.end(); n_it++) { if(n_it->loophead==SSA.nodes.end()) continue; symbol_exprt lsguard= SSA.name(SSA.guard_symbol(), local_SSAt::LOOP_SELECT, n_it->location); ssa_unwinder.get(entry_point).unwinder_rename(lsguard, *n_it, true); loophead_selects.push_back(not_exprt(lsguard)); } // iterate over assumptions exprt::operandst assumptions; for(local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin(); n_it!=SSA.nodes.end(); n_it++) { for(local_SSAt::nodet::assumptionst::const_iterator a_it=n_it->assumptions.begin(); a_it!=n_it->assumptions.end(); a_it++) { std::cout << "Assumption:: " << from_expr(*a_it) << std::endl; assumptions.push_back(*a_it); } } // iterate over assertions std::list<local_SSAt::nodest::const_iterator> assertion_nodes; SSA.find_nodes(i_it, assertion_nodes); std::cout << "The number of assertions are: " << assertion_nodes.size() << std::endl; exprt::operandst assertions; for(std::list<local_SSAt::nodest::const_iterator>::const_iterator n_it=assertion_nodes.begin(); n_it!=assertion_nodes.end(); n_it++) { for(local_SSAt::nodet::assertionst::const_iterator a_it=(*n_it)->assertions.begin(); a_it!=(*n_it)->assertions.end(); a_it++) { assertions.push_back(*a_it); } } // if(simplify) property=simplify_expr(property, SSA.ns); property_map[property_id].location=i_it; // TODO: make the solver incremental // configure components of acdl solver // domain acdl_domaint domain(options, SSA, ssa_db, ssa_local_unwinder); domain.set_message_handler(get_message_handler()); // worklist heuristics std::unique_ptr<acdl_worklist_baset> worklist; if(options.get_option("propagate")=="forward") worklist=std::unique_ptr<acdl_worklist_baset>( new acdl_worklist_forwardt()); if(options.get_option("propagate")=="backward") worklist=std::unique_ptr<acdl_worklist_baset>( new acdl_worklist_backwardt()); else if(options.get_option("propagate")=="chaotic") worklist=std::unique_ptr<acdl_worklist_baset>( new acdl_worklist_orderedt()); // conflict analysis heuristics std::unique_ptr<acdl_analyze_conflict_baset> conflict_analysis; if(options.get_option("learning")=="first-uip") // TODO: no 'new' with base class! conflict_analysis=std::unique_ptr<acdl_analyze_conflict_baset>( new acdl_analyze_conflict_baset(domain)); // decision heuristics std::unique_ptr<acdl_decision_heuristics_baset> decision_heuristics; if(options.get_option("decision")=="random") decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>( new acdl_decision_heuristics_randt(domain)); else if(options.get_option("decision")=="ordered") decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>( new acdl_decision_heuristics_orderedt(domain)); else if(options.get_option("decision")=="octagon") decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>( new acdl_decision_heuristics_octagont(domain)); else if(options.get_option("decision")=="berkmin") decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>( new acdl_decision_heuristics_berkmint(domain, *conflict_analysis)); else if(options.get_option("decision")=="range") decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>( new acdl_decision_heuristics_ranget(domain)); // now instantiate solver acdl_solvert acdl_solver( options, domain, *decision_heuristics, *worklist, *conflict_analysis); acdl_solver.set_message_handler(get_message_handler()); property_map[property_id].result= acdl_solver( ssa_db.get(goto_model.goto_functions.entry_point()), conjunction(assertions), conjunction(loophead_selects), conjunction(assumptions)); } summary_checker_baset::resultt result=property_checkert::PASS; for(property_mapt::const_iterator p_it=property_map.begin(); p_it!=property_map.end(); p_it++) { if(p_it->second.result==FAIL) return property_checkert::FAIL; if(p_it->second.result==UNKNOWN) result=property_checkert::UNKNOWN; } return result; }
exprt c_typecheck_baset::do_initializer_list( const exprt &value, const typet &type, bool force_constant) { assert(value.id()==ID_initializer_list); const typet &full_type=follow(type); exprt result; if(full_type.id()==ID_struct || full_type.id()==ID_union || full_type.id()==ID_vector) { // start with zero everywhere result=zero_initializer(type, value.source_location(), *this, get_message_handler()); } else if(full_type.id()==ID_array) { if(to_array_type(full_type).size().is_nil()) { // start with empty array result=exprt(ID_array, full_type); result.add_source_location()=value.source_location(); } else { // start with zero everywhere result=zero_initializer(type, value.source_location(), *this, get_message_handler()); } // 6.7.9, 14: An array of character type may be initialized by a character // string literal or UTF-8 string literal, optionally enclosed in braces. if(value.operands().size()>=1 && value.op0().id()==ID_string_constant && (full_type.subtype().id()==ID_signedbv || full_type.subtype().id()==ID_unsignedbv) && full_type.subtype().get(ID_width)==char_type().get(ID_width)) { if(value.operands().size()>1) { warning().source_location=value.find_source_location(); warning() << "ignoring excess initializers" << eom; } return do_initializer_rec(value.op0(), type, force_constant); } } else { // The initializer for a scalar shall be a single expression, // * optionally enclosed in braces. * if(value.operands().size()==1) return do_initializer_rec(value.op0(), type, force_constant); err_location(value); error() << "cannot initialize `" << to_string(full_type) << "' with an initializer list" << eom; throw 0; } designatort current_designator; designator_enter(type, current_designator); forall_operands(it, value) { do_designated_initializer( result, current_designator, *it, force_constant); // increase designator -- might go up increment_designator(current_designator); }
satcheckt::resultt ranking_synthesis_satt::check_for_counterexample( const exprt &templ, c_valuest &c_values, fine_timet &conversion_time, fine_timet &solver_time) { satcheckt::resultt result; satcheckt solver; bv_pointerst converter(ns, solver); solver.set_message_handler(get_message_handler()); solver.set_verbosity(verbosity); converter.set_message_handler(get_message_handler()); converter.set_verbosity(verbosity); show_coefficients(c_values); fine_timet before = current_time(); converter.set_to_true(templ); for(c_valuest::const_iterator it=c_values.begin(); it!=c_values.end(); it++) { equal_exprt eq; if(it->first.get("identifier")=="termination::constant$C") { mp_integer cval; if(to_integer(largest_constant, cval)) throw "number conversion failed"; mp_integer b=cval * it->second; eq=equal_exprt(it->first, from_integer(b, it->first.type())); } else eq=equal_exprt(it->first, from_integer(it->second, it->first.type())); converter.set_to_true(eq); } conversion_time+=current_time()-before; before = current_time(); result=solver.prop_solve(); solver_time+=current_time()-before; solver_calls++; std::string output; if(result==satcheckt::P_SATISFIABLE) show_counterexample(converter); else if(result==satcheckt::P_UNSATISFIABLE) output += " ... YES!\n"; else output += "ERROR\n"; debug(output); return result; }
cbmc_solverst::solvert* cbmc_solverst::get_smt2(smt2_dect::solvert solver) { no_beautification(); const std::string &filename=options.get_option("outfile"); if(filename=="") { if(solver==smt2_dect::solvert::GENERIC) { error() << "please use --outfile" << eom; throw 0; } smt2_dect *smt2_dec= new smt2_dect( ns, "cbmc", "Generated by CBMC " CBMC_VERSION, "QF_AUFBV", solver); if(options.get_bool_option("fpa")) smt2_dec->use_FPA_theory=true; return new solvert(smt2_dec); } else if(filename=="-") { smt2_convt *smt2_conv= new smt2_convt( ns, "cbmc", "Generated by CBMC " CBMC_VERSION, "QF_AUFBV", solver, std::cout); if(options.get_bool_option("fpa")) smt2_conv->use_FPA_theory=true; smt2_conv->set_message_handler(get_message_handler()); return new solvert(smt2_conv); } else { #ifdef _MSC_VER std::ofstream *out=new std::ofstream(widen(filename)); #else std::ofstream *out=new std::ofstream(filename); #endif if(!*out) { error() << "failed to open " << filename << eom; throw 0; } smt2_convt *smt2_conv= new smt2_convt( ns, "cbmc", "Generated by CBMC " CBMC_VERSION, "QF_AUFBV", solver, *out); if(options.get_bool_option("fpa")) smt2_conv->use_FPA_theory=true; smt2_conv->set_message_handler(get_message_handler()); return new solvert(smt2_conv, out); } }
void java_bytecode_convert_classt::convert(const classt &c) { class_typet class_type; class_type.set_tag(c.name); class_type.set(ID_base_name, c.name); if(c.is_enum) class_type.set( ID_java_enum_static_unwind, std::to_string(c.enum_elements+1)); if(!c.extends.empty()) { symbol_typet base("java::"+id2string(c.extends)); class_type.add_base(base); class_typet::componentt base_class_field; base_class_field.type()=base; base_class_field.set_name("@"+id2string(c.extends)); base_class_field.set_base_name("@"+id2string(c.extends)); base_class_field.set_pretty_name("@"+id2string(c.extends)); class_type.components().push_back(base_class_field); } // interfaces are recorded as bases for(const auto &interface : c.implements) { symbol_typet base("java::"+id2string(interface)); class_type.add_base(base); } // produce class symbol symbolt new_symbol; new_symbol.base_name=c.name; new_symbol.pretty_name=c.name; new_symbol.name="java::"+id2string(c.name); class_type.set(ID_name, new_symbol.name); new_symbol.type=class_type; new_symbol.mode=ID_java; new_symbol.is_type=true; symbolt *class_symbol; // add before we do members if(symbol_table.move(new_symbol, class_symbol)) { error() << "failed to add class symbol " << new_symbol.name << eom; throw 0; } // now do fields for(const auto &field : c.fields) convert(*class_symbol, field); // now do methods for(const auto &method : c.methods) java_bytecode_convert_method( *class_symbol, method, symbol_table, get_message_handler(), disable_runtime_checks, max_array_length); // is this a root class? if(c.extends.empty()) java_root_class(*class_symbol); }
bool cbmc_parseoptionst::get_goto_program( const optionst &options, bmct &bmc, goto_functionst &goto_functions) { if(cmdline.args.size()==0) { error("Please provide a program to verify"); return true; } try { if(cmdline.args.size()==1 && is_goto_binary(cmdline.args[0])) { status("Reading GOTO program from file"); if(read_goto_binary(cmdline.args[0], context, goto_functions, get_message_handler())) return true; config.ansi_c.set_from_context(context); if(cmdline.isset("show-symbol-table")) { show_symbol_table(); return true; } if(context.symbols.find(ID_main)==context.symbols.end()) { error("The goto binary has no entry point; please complete linking"); return true; } } else { if(parse()) return true; if(typecheck()) return true; if(get_modules(bmc)) return true; if(final()) return true; // we no longer need any parse trees or language files clear_parse(); if(cmdline.isset("show-symbol-table")) { show_symbol_table(); return true; } if(context.symbols.find(ID_main)==context.symbols.end()) { error("No entry point; please provide a main function"); return true; } status("Generating GOTO Program"); goto_convert( context, options, goto_functions, ui_message_handler); } // finally add the library status("Adding CPROVER library"); link_to_library( context, goto_functions, options, ui_message_handler); if(process_goto_program(options, goto_functions)) return true; } catch(const char *e) { error(e); return true; } catch(const std::string e) { error(e); return true; } catch(int) { return true; } catch(std::bad_alloc) { error("Out of memory"); return true; } return false; }
int symex_parseoptionst::doit() { if(cmdline.isset("version")) { std::cout << CBMC_VERSION << std::endl; return 0; } register_language(new_ansi_c_language); register_language(new_cpp_language); // // command line options // optionst options; get_command_line_options(options); eval_verbosity(); goto_functionst goto_functions; if(get_goto_program(options, goto_functions)) return 6; label_properties(goto_functions); if(cmdline.isset("show-properties")) { const namespacet ns(symbol_table); show_properties(ns, get_ui(), goto_functions); return 0; } if(set_properties(goto_functions)) return 7; if(cmdline.isset("show-locs")) { const namespacet ns(symbol_table); locst locs(ns); locs.build(goto_functions); locs.output(std::cout); return 0; } // do actual Symex try { const namespacet ns(symbol_table); path_searcht path_search(ns); path_search.set_message_handler(get_message_handler()); if(cmdline.isset("depth")) path_search.set_depth_limit(unsafe_string2unsigned(cmdline.get_value("depth"))); if(cmdline.isset("context-bound")) path_search.set_context_bound(unsafe_string2unsigned(cmdline.get_value("context-bound"))); if(cmdline.isset("unwind")) path_search.set_unwind_limit(unsafe_string2unsigned(cmdline.get_value("unwind"))); if(cmdline.isset("show-vcc")) { path_search.show_vcc=true; path_search(goto_functions); return 0; } // do actual symex switch(path_search(goto_functions)) { case safety_checkert::SAFE: report_properties(path_search.property_map); report_success(); return 0; case safety_checkert::UNSAFE: report_properties(path_search.property_map); report_failure(); return 10; default: return 8; } } catch(const std::string error_msg) { error() << error_msg << messaget::eom; return 8; } catch(const char *error_msg) { error() << error_msg << messaget::eom; return 8; } #if 0 // let's log some more statistics debug() << "Memory consumption:" << messaget::endl; memory_info(debug()); debug() << eom; #endif }
void summarizer_bw_termt::do_summary_term( const function_namet &function_name, local_SSAt &SSA, const summaryt &old_summary, summaryt &summary, bool context_sensitive) { status() << "Computing preconditions for termination" << eom; // solver incremental_solvert &solver=ssa_db.get_solver(function_name); solver.set_message_handler(get_message_handler()); // templates for ranking functions template_generator_rankingt template_generator1( options, ssa_db, ssa_unwinder.get(function_name)); template_generator1.set_message_handler(get_message_handler()); template_generator1(solver.next_domain_number(), SSA, true); // templates for backward summary template_generator_summaryt template_generator2( options, ssa_db, ssa_unwinder.get(function_name)); template_generator2.set_message_handler(get_message_handler()); template_generator2(solver.next_domain_number(), SSA, false); exprt::operandst bindings; exprt::operandst postcond; // backward summaries ssa_inliner.get_summaries(SSA, false, postcond, bindings); collect_postconditions(function_name, SSA, summary, postcond, true); // prepare solver solver << SSA; solver.new_context(); solver << SSA.get_enabling_exprs(); solver << old_summary.fw_precondition; solver << old_summary.fw_invariant; solver << ssa_inliner.get_summaries(SSA); // forward summaries solver << conjunction(bindings); // bindings for backward summaries #if 0 // compute preconditions individually // TODO: this should be done more transparently for(unsigned i=0; i<postcond.size(); i++) { exprt::operandst postcond2; postcond2.push_back(postcond[i]); compute_precondition( SSA, summary, postcond2, solver, template_generator2, context_sensitive); } postcond.clear(); #endif if(template_generator1.all_vars().empty()) { compute_precondition( SSA, summary, postcond, solver, template_generator2, context_sensitive); solver.pop_context(); return; } summary.bw_precondition=false_exprt(); // initialize unsigned number_disjuncts=0; while(number_disjuncts++<MAX_PRECONDITION_DISJUNCTS) { // bootstrap preconditions exprt termination_argument; if(!bootstrap_preconditions( SSA, summary, solver, template_generator1, template_generator2, termination_argument)) { break; } // compute precondition // compute for individual termination arguments separately // TODO: this should be done more transparently if(termination_argument.id()==ID_and) { for(unsigned i=0; i<termination_argument.operands().size(); i++) { postcond.push_back(termination_argument.operands()[i]); exprt precondition= compute_precondition( SSA, summary, postcond, solver, template_generator2, context_sensitive); // join results if(summary.termination_argument.is_nil()) { summary.termination_argument= implies_exprt(precondition, termination_argument); } else { summary.termination_argument= and_exprt( summary.termination_argument, implies_exprt(precondition, termination_argument)); } // TODO: this is a bit asymmetric: // the first precondition is joined with all other sources // of non-termination (calls, bw calling context) postcond.clear(); } } else // do not split termination arguments { postcond.push_back(termination_argument); exprt precondition= compute_precondition( SSA, summary, postcond, solver, template_generator2, context_sensitive); // join results if(summary.termination_argument.is_nil()) { summary.termination_argument= implies_exprt(precondition, termination_argument); } else { summary.termination_argument= and_exprt( summary.termination_argument, implies_exprt(precondition, termination_argument)); } // TODO: this is a bit asymmetric: // the first precondition is joined with all other sources // of non-termination (calls, bw calling context) postcond.clear(); } } solver.pop_context(); }
bool symex_parseoptionst::get_goto_program( const optionst &options, goto_functionst &goto_functions) { if(cmdline.args.size()==0) { error() << "Please provide a program to verify" << eom; return true; } try { if(cmdline.args.size()==1 && is_goto_binary(cmdline.args[0])) { status() << "Reading GOTO program from file" << eom; if(read_goto_binary(cmdline.args[0], symbol_table, goto_functions, get_message_handler())) return true; config.ansi_c.set_from_symbol_table(symbol_table); if(cmdline.isset("show-symbol-table")) { show_symbol_table(); return true; } irep_idt entry_point=goto_functions.entry_point(); if(symbol_table.symbols.find(entry_point)==symbol_table.symbols.end()) { error() << "The goto binary has no entry point; please complete linking" << eom; return true; } } else if(cmdline.isset("show-parse-tree")) { if(cmdline.args.size()!=1) { error() << "Please give one source file only" << eom; return true; } std::string filename=cmdline.args[0]; #ifdef _MSC_VER std::ifstream infile(widen(filename).c_str()); #else std::ifstream infile(filename.c_str()); #endif if(!infile) { error() << "failed to open input file `" << filename << "'" << eom; return true; } languaget *language=get_language_from_filename(filename); if(language==NULL) { error() << "failed to figure out type of file `" << filename << "'" << eom; return true; } language->set_message_handler(get_message_handler()); status("Parsing", filename); if(language->parse(infile, filename)) { error() << "PARSING ERROR" << eom; return true; } language->show_parse(std::cout); return true; } else { if(parse()) return true; if(typecheck()) return true; if(final()) return true; // we no longer need any parse trees or language files clear_parse(); if(cmdline.isset("show-symbol-table")) { show_symbol_table(); return true; } irep_idt entry_point=goto_functions.entry_point(); if(symbol_table.symbols.find(entry_point)==symbol_table.symbols.end()) { error() << "No entry point; please provide a main function" << eom; return true; } status() << "Generating GOTO Program" << eom; goto_convert(symbol_table, goto_functions, ui_message_handler); } // finally add the library status() << "Adding CPROVER library" << eom; link_to_library(symbol_table, goto_functions, ui_message_handler); if(process_goto_program(options, goto_functions)) return true; } catch(const char *e) { error() << e << eom; return true; } catch(const std::string e) { error() << e << eom; return true; } catch(int) { return true; } catch(std::bad_alloc) { error() << "Out of memory" << eom; return true; } return false; }
RedClient::RedClient(Application& application) : RedChannel(*this, SPICE_CHANNEL_MAIN, 0, new MainChannelLoop(*this)) , _application (application) , _port (-1) , _sport (-1) , _protocol (0) , _connection_id (0) , _mouse_mode (SPICE_MOUSE_MODE_SERVER) , _notify_disconnect (false) , _auto_display_res (false) , _agent_reply_wait_type (VD_AGENT_END_MESSAGE) , _aborting (false) , _msg_attach_channels_sent(false) , _agent_connected (false) , _agent_mon_config_sent (false) , _agent_disp_config_sent (false) , _agent_msg (new VDAgentMessage) , _agent_msg_data (NULL) , _agent_msg_pos (0) , _agent_out_msg (NULL) , _agent_out_msg_size (0) , _agent_out_msg_pos (0) , _agent_tokens (0) , _agent_timer (new AgentTimer(this)) , _agent_caps_size(0) , _agent_caps(NULL) , _migrate (*this) , _glz_window (_glz_debug) , _during_migration (false) { Platform::set_clipboard_listener(this); MainChannelLoop* message_loop = static_cast<MainChannelLoop*>(get_message_handler()); uint32_t default_caps_size = SPICE_N_ELEMENTS(default_agent_caps); _agent_caps_size = VD_AGENT_CAPS_SIZE; ASSERT(VD_AGENT_CAPS_SIZE >= default_caps_size); _agent_caps = new uint32_t[_agent_caps_size]; memcpy(_agent_caps, default_agent_caps, default_caps_size); message_loop->set_handler(SPICE_MSG_MIGRATE, &RedClient::handle_migrate); message_loop->set_handler(SPICE_MSG_SET_ACK, &RedClient::handle_set_ack); message_loop->set_handler(SPICE_MSG_PING, &RedClient::handle_ping); message_loop->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &RedClient::handle_wait_for_channels); message_loop->set_handler(SPICE_MSG_DISCONNECTING, &RedClient::handle_disconnect); message_loop->set_handler(SPICE_MSG_NOTIFY, &RedClient::handle_notify); message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_BEGIN, &RedClient::handle_migrate_begin); message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_CANCEL, &RedClient::handle_migrate_cancel); message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_END, &RedClient::handle_migrate_end); message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST, &RedClient::handle_migrate_switch_host); message_loop->set_handler(SPICE_MSG_MAIN_INIT, &RedClient::handle_init); message_loop->set_handler(SPICE_MSG_MAIN_CHANNELS_LIST, &RedClient::handle_channels); message_loop->set_handler(SPICE_MSG_MAIN_MOUSE_MODE, &RedClient::handle_mouse_mode); message_loop->set_handler(SPICE_MSG_MAIN_MULTI_MEDIA_TIME, &RedClient::handle_mm_time); message_loop->set_handler(SPICE_MSG_MAIN_AGENT_CONNECTED, &RedClient::handle_agent_connected); message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DISCONNECTED, &RedClient::handle_agent_disconnected); message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DATA, &RedClient::handle_agent_data); message_loop->set_handler(SPICE_MSG_MAIN_AGENT_TOKEN, &RedClient::handle_agent_tokens); set_capability(SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE); start(); }
void goto_fence_inserter_parse_optionst::instrument_goto_program( goto_functionst &goto_functions) { optionst options; // unwind loops if(cmdline.isset("unwind")) { status() << "Unwinding loops" << eom; options.set_option("unwind", cmdline.get_value("unwind")); } // we add the library, as some analyses benefit status() << "Adding CPROVER library" << eom; link_to_library(symbol_table, goto_functions, ui_message_handler); namespacet ns(symbol_table); if( cmdline.isset("mm") || cmdline.isset("all-shared") || cmdline.isset("volatile") || cmdline.isset("pensieve") || cmdline.isset("naive") || cmdline.isset("all-shared-aeg") ) { if(cmdline.isset("remove-function-pointers")) { status() << "remove soundly function pointers" << eom; remove_function_pointers(symbol_table, goto_functions, cmdline.isset("pointer-check")); } if(cmdline.isset("async")) { status() << "Replace pthread_creates by __CPROVER_ASYNC_0:" << eom; replace_async(ns, goto_functions); goto_functions.update(); } // do partial inlining status() << "Partial Inlining" << eom; goto_partial_inline(goto_functions, ns, ui_message_handler); if(cmdline.isset("const-function-pointer-propagation")) { /* propagate const pointers to functions */ status() << "Propagate Constant Function Pointers" << eom; propagate_const_function_pointers(symbol_table, goto_functions, get_message_handler()); } // goto_functions.output(ns, std::cout); // return; #if 0 status() << "Function Pointer Removal" << eom; remove_function_pointers(symbol_table, goto_functions, cmdline.isset("pointer-check")); #endif #if 0 // do partial inlining status() << "Partial Inlining" << eom; goto_partial_inline(goto_functions, ns, ui_message_handler); #endif status() << "Pointer Analysis" << eom; #ifdef POINTER_ANALYSIS_FI value_set_analysis_fit value_set_analysis(ns); #else value_set_analysist value_set_analysis(ns); #endif #ifndef LOCAL_MAY value_set_analysis(goto_functions); #endif status() << "Removing asm code" << eom; remove_asm(symbol_table, goto_functions); goto_functions.update(); if(cmdline.isset("all-shared")) { status() << "Shared variables accesses detection" << eom; fence_all_shared(get_message_handler(), value_set_analysis, symbol_table, goto_functions); // simple analysis, coupled with script to insert; // does not transform the goto-binary return; } if(cmdline.isset("all-shared-aeg")) { status() << "Shared variables accesses detection (CF)" << eom; fence_all_shared_aeg(get_message_handler(), value_set_analysis, symbol_table, goto_functions); // simple analysis, coupled with script to insert; // does not transform the goto-binary return; } else if(cmdline.isset("volatile")) { status() << "Detection of variables declared volatile" << eom; fence_volatile(get_message_handler(), value_set_analysis, symbol_table, goto_functions); // simple analysis, coupled with script to insert; // does not transform the goto-binary return; } else if(cmdline.isset("pensieve") || cmdline.isset("naive")) { status() << "Delay-set analysis" << eom; const unsigned unwind_loops= cmdline.isset("unwind") ? unsafe_string2unsigned(cmdline.get_value("unwind")) : 0; const unsigned max_po_trans= cmdline.isset("max-po-trans") ? unsafe_string2unsigned(cmdline.get_value("max-po-trans")) : 0; fence_pensieve( value_set_analysis, symbol_table, goto_functions, unwind_loops, max_po_trans, !cmdline.isset("no-po-rendering"), cmdline.isset("render-cluster-file"), cmdline.isset("render-cluster-function"), cmdline.isset("naive"), get_message_handler()); // simple analysis, coupled with script to insert; // does not transform the goto-binary return; } else if(cmdline.isset("mm")) { std::string mm=cmdline.get_value("mm"); memory_modelt model; status() << "Fence detection for " << mm << " via critical cycles and ILP" << eom; // strategy of instrumentation instrumentation_strategyt inst_strategy; if(cmdline.isset("one-event-per-cycle")) inst_strategy=one_event_per_cycle; else if(cmdline.isset("minimum-interference")) inst_strategy=min_interference; else if(cmdline.isset("read-first")) inst_strategy=read_first; else if(cmdline.isset("write-first")) inst_strategy=write_first; else if(cmdline.isset("my-events")) inst_strategy=my_events; else /* default: instruments all unsafe pairs */ inst_strategy=all; const unsigned unwind_loops = cmdline.isset("unwind") ? unsafe_string2unsigned(cmdline.get_value("unwind")) : 0; const unsigned max_var = cmdline.isset("max-var") ? unsafe_string2unsigned(cmdline.get_value("max-var")) : 0; const unsigned max_po_trans = cmdline.isset("max-po-trans") ? unsafe_string2unsigned(cmdline.get_value("max-po-trans")) : 0; if(mm=="tso") { status() << "Adding weak memory (TSO) Instrumentation" << eom; model=TSO; } else if(mm=="pso") { status() << "Adding weak memory (PSO) Instrumentation" << eom; model=PSO; } else if(mm=="rmo") { status() << "Adding weak memory (RMO) Instrumentation" << eom; model=RMO; } else if(mm=="power") { status() << "Adding weak memory (Power) Instrumentation" << eom; model=Power; } else { status/*error*/() << "Unknown weak memory model" << eom; model=Unknown; } /* inference mode */ infer_modet infer_mode=INFER; if(cmdline.isset("userdef")) infer_mode=USER_DEF; loop_strategyt loops=arrays_only; if(cmdline.isset("force-loop-duplication")) loops=all_loops; if(cmdline.isset("no-loop-duplication")) loops=no_loop; /*if(model!=Unknown)*/ fence_weak_memory( model, value_set_analysis, symbol_table, goto_functions, cmdline.isset("scc"), inst_strategy, unwind_loops, !cmdline.isset("cfg-kill"), cmdline.isset("no-dependencies"), loops, max_var, max_po_trans, !cmdline.isset("no-po-rendering"), cmdline.isset("render-cluster-file"), cmdline.isset("render-cluster-function"), cmdline.isset("cav11"), cmdline.isset("hide-internals"), cmdline.isset("print-graph"), infer_mode, get_message_handler(), cmdline.isset("ignore-arrays")); } } // add failed symbols add_failed_symbols(symbol_table); // recalculate numbers, etc. goto_functions.update(); // add loop ids goto_functions.compute_loop_numbers(); // label the assertions label_properties(goto_functions); }