bool java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, message_handlert &message_handler) { symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE); code_blockt &code_block=to_code_block(to_code(initialize_symbol.value)); // we need to zero out all static variables for(symbol_tablet::symbolst::const_iterator it=symbol_table.symbols.begin(); it!=symbol_table.symbols.end(); it++) { if(it->second.type.id()!=ID_code && it->second.is_lvalue && it->second.is_state_var && it->second.is_static_lifetime && it->second.value.is_not_nil() && it->second.mode==ID_java) { code_assignt assignment(it->second.symbol_expr(), it->second.value); code_block.add(assignment); } } // we now need to run all the <clinit> methods for(symbol_tablet::symbolst::const_iterator it=symbol_table.symbols.begin(); it!=symbol_table.symbols.end(); it++) { if(it->second.base_name=="<clinit>" && it->second.type.id()==ID_code && it->second.mode==ID_java) { code_function_callt function_call; function_call.lhs()=nil_exprt(); function_call.function()=it->second.symbol_expr(); code_block.add(function_call); } } return false; }
bool static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, message_handlert &message_handler) { namespacet ns(symbol_table); symbol_tablet::symbolst::iterator s_it= symbol_table.symbols.find(INITIALIZE_FUNCTION); if(s_it==symbol_table.symbols.end()) return false; symbolt &init_symbol=s_it->second; init_symbol.value=code_blockt(); init_symbol.value.add_source_location()=source_location; code_blockt &dest=to_code_block(to_code(init_symbol.value)); // add the magic label to hide dest.add(code_labelt("__CPROVER_HIDE", code_skipt())); // do assignments based on "value" // sort alphabetically for reproducible results std::set<std::string> symbols; forall_symbols(it, symbol_table.symbols) symbols.insert(id2string(it->first)); for(const std::string &id : symbols) { const symbolt &symbol=ns.lookup(id); const irep_idt &identifier=symbol.name; if(!symbol.is_static_lifetime) continue; if(symbol.is_type || symbol.is_macro) continue; // special values if(identifier==CPROVER_PREFIX "constant_infinity_uint" || identifier==CPROVER_PREFIX "memory" || identifier=="__func__" || identifier=="__FUNCTION__" || identifier=="__PRETTY_FUNCTION__" || identifier=="argc'" || identifier=="argv'" || identifier=="envp'" || identifier=="envp_size'") continue; // just for linking if(has_prefix(id, CPROVER_PREFIX "architecture_")) continue; const typet &type=ns.follow(symbol.type); // check type if(type.id()==ID_code || type.id()==ID_empty) continue; // We won't try to initialize any symbols that have // remained incomplete. if(symbol.value.is_nil() && symbol.is_extern) // Compilers would usually complain about these // symbols being undefined. continue; if(type.id()==ID_array && to_array_type(type).size().is_nil()) { // C standard 6.9.2, paragraph 5 // adjust the type to an array of size 1 symbol_tablet::symbolst::iterator it= symbol_table.symbols.find(identifier); assert(it!=symbol_table.symbols.end()); it->second.type=type; it->second.type.set(ID_size, from_integer(1, size_type())); } if(type.id()==ID_incomplete_struct || type.id()==ID_incomplete_union) continue; // do not initialize if(symbol.value.id()==ID_nondet) continue; // do not initialize exprt rhs; if(symbol.value.is_nil()) { try { namespacet ns(symbol_table); rhs=zero_initializer(symbol.type, symbol.location, ns, message_handler); assert(rhs.is_not_nil()); } catch(...) { return true; } } else rhs=symbol.value; code_assignt code(symbol.symbol_expr(), rhs); code.add_source_location()=symbol.location; dest.move_to_operands(code); } // call designated "initialization" functions for(const std::string &id : symbols) { const symbolt &symbol=ns.lookup(id); if(symbol.type.id()==ID_code && to_code_type(symbol.type).return_type().id()==ID_constructor) { code_function_callt function_call; function_call.function()=symbol.symbol_expr(); function_call.add_source_location()=source_location; dest.move_to_operands(function_call); } } return false; }
void c_typecheck_baset::typecheck_for(codet &code) { if(code.operands().size()!=4) { err_location(code); error() << "for expected to have four operands" << eom; throw 0; } // the "for" statement has an implicit block around it, // since code.op0() may contain declarations // // we therefore transform // // for(a;b;c) d; // // to // // { a; for(;b;c) d; } // // if config.ansi_c.for_has_scope if(!config.ansi_c.for_has_scope || code.op0().is_nil()) { if(code.op0().is_not_nil()) typecheck_code(to_code(code.op0())); if(code.op1().is_nil()) code.op1()=true_exprt(); else { typecheck_expr(code.op1()); implicit_typecast_bool(code.op1()); } if(code.op2().is_not_nil()) typecheck_expr(code.op2()); if(code.op3().is_not_nil()) { // save & set flags bool old_break_is_allowed=break_is_allowed; bool old_continue_is_allowed=continue_is_allowed; break_is_allowed=continue_is_allowed=true; // recursive call if(to_code(code.op3()).get_statement()==ID_decl_block) { code_blockt code_block; code_block.add_source_location()=code.op3().source_location(); code_block.move_to_operands(code.op3()); code.op3().swap(code_block); } typecheck_code(to_code(code.op3())); // restore flags break_is_allowed=old_break_is_allowed; continue_is_allowed=old_continue_is_allowed; } } else { code_blockt code_block; code_block.add_source_location()=code.source_location(); if(to_code(code.op3()).get_statement()==ID_block) code_block.set( ID_C_end_location, to_code_block(to_code(code.op3())).end_location()); else code_block.set( ID_C_end_location, code.op3().source_location());; code_block.reserve_operands(2); code_block.move_to_operands(code.op0()); code.op0().make_nil(); code_block.move_to_operands(code); code.swap(code_block); typecheck_code(code); // recursive call } typecheck_spec_expr(code, ID_C_spec_loop_invariant); }
bool java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, message_handlert &message_handler, bool assume_init_pointers_not_null, unsigned max_nondet_array_length) { symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE); code_blockt &code_block=to_code_block(to_code(initialize_symbol.value)); // We need to zero out all static variables, or nondet-initialize if they're // external. Iterate over a copy of the symtab, as its iterators are // invalidated by object_factory: std::list<irep_idt> symbol_names; for(const auto &entry : symbol_table.symbols) symbol_names.push_back(entry.first); for(const auto &symname : symbol_names) { const symbolt &sym=symbol_table.lookup(symname); if(should_init_symbol(sym)) { if(sym.value.is_nil() && sym.type!=empty_typet()) { bool allow_null=!assume_init_pointers_not_null; if(allow_null) { std::string namestr=id2string(sym.symbol_expr().get_identifier()); const std::string suffix="@class_model"; // Static '.class' fields are always non-null. if(has_suffix(namestr, suffix)) allow_null=false; if(allow_null && has_prefix( namestr, "java::java.lang.String.Literal")) allow_null=false; } auto newsym=object_factory( sym.type, code_block, allow_null, symbol_table, max_nondet_array_length, source_location, message_handler); code_assignt assignment(sym.symbol_expr(), newsym); code_block.add(assignment); } else if(sym.value.is_not_nil()) { code_assignt assignment(sym.symbol_expr(), sym.value); assignment.add_source_location()=source_location; code_block.add(assignment); } } } // we now need to run all the <clinit> methods for(symbol_tablet::symbolst::const_iterator it=symbol_table.symbols.begin(); it!=symbol_table.symbols.end(); it++) { if(it->second.base_name=="<clinit>" && it->second.type.id()==ID_code && it->second.mode==ID_java) { code_function_callt function_call; function_call.lhs()=nil_exprt(); function_call.function()=it->second.symbol_expr(); function_call.add_source_location()=source_location; code_block.add(function_call); } } return false; }