/// does not replace object in address_of expressions bool replace_symbol_extt::replace(exprt &dest) const { bool result=true; // first look at type if(have_to_replace(dest.type())) if(!replace_symbolt::replace(dest.type())) result=false; // now do expression itself if(!have_to_replace(dest)) return result; // do not replace object in address_of expressions if(dest.id()==ID_address_of) { const exprt &object = to_address_of_expr(dest).object(); if(object.id()==ID_symbol) { expr_mapt::const_iterator it= expr_map.find(object.get(ID_identifier)); if(it!=expr_map.end()) return false; } } else if(dest.id()==ID_symbol) { expr_mapt::const_iterator it= expr_map.find(dest.get(ID_identifier)); if(it!=expr_map.end()) { dest=it->second; return false; } } Forall_operands(it, dest) if(!replace(*it)) result=false; const irept &c_sizeof_type=dest.find(ID_C_c_sizeof_type); if(c_sizeof_type.is_not_nil() && !replace_symbolt::replace( static_cast<typet&>(dest.add(ID_C_c_sizeof_type)))) result=false; const irept &va_arg_type=dest.find(ID_C_va_arg_type); if(va_arg_type.is_not_nil() && !replace_symbolt::replace(static_cast<typet&>(dest.add(ID_C_va_arg_type)))) result=false; return result; }
exprt modelchecker_smvt::convert_schoose_expression( const exprt &expr, const exprt &guard) { nondet_symbolst::const_iterator it= nondet_symbols.find(static_cast<const exprt &>(expr.find("expression"))); if(it==nondet_symbols.end()) throw "failed to find nondet_symbol"; exprt nondet("symbol", typet("bool")); nondet.set("identifier", it->second); exprt conj("and", typet("bool")); conj.move_to_operands(nondet); conj.copy_to_operands(expr.op1()); conj.op1().make_not(); //exprt disj("or", typet("bool")); //disj.copy_to_operands(expr.op0(), guard); exprt target("or", typet("bool")); target.move_to_operands(conj); target.copy_to_operands(expr.op0()); return target; }
void modelchecker_smvt::instantiate_expression(exprt &expr) { Forall_operands(it, expr) instantiate_expression(*it); if(expr.id()==ID_predicate_symbol) { unsigned p=atoi(expr.get(ID_identifier).c_str()); expr.id(ID_symbol); expr.set(ID_identifier, variable_names[p]); } else if(expr.id()==ID_predicate_next_symbol) { unsigned p=atoi(expr.get(ID_identifier).c_str()); expr.id(ID_next_symbol); expr.set(ID_identifier, variable_names[p]); } else if(expr.id()==ID_nondet_symbol) { nondet_symbolst::const_iterator it= nondet_symbols.find( static_cast<const exprt &>(expr.find("expression"))); if(it==nondet_symbols.end()) throw "failed to find nondet_symbol"; typet type=expr.type(); expr=exprt(ID_symbol, type); expr.set(ID_identifier, it->second); } }
void replace_location( exprt &dest, const source_locationt &new_location) { Forall_operands(it, dest) replace_location(*it, new_location); if(dest.find(ID_C_source_location).is_not_nil()) replace_location(dest.add_source_location(), new_location); }
void modelcheckert::get_nondet_symbols(const exprt &expr) { forall_operands(it, expr) get_nondet_symbols(*it); if(expr.id()==ID_nondet_symbol || expr.id()==ID_bp_schoose) { nondet_symbols.insert(std::pair<exprt, std::string> (static_cast<const exprt &>(expr.find(ID_expression)), "nondet"+i2string(nondet_symbols.size()))); } }
std::string expr2javat::convert_java_new( const exprt &src, unsigned precedence) { std::string dest; if(src.get(ID_statement)==ID_java_new_array) { dest="new"; std::string tmp_size= convert(static_cast<const exprt &>(src.find(ID_size))); dest+=' '; dest+=convert(src.type().subtype()); dest+='['; dest+=tmp_size; dest+=']'; } else dest="new "+convert(src.type().subtype()); return dest; }
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 } }
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(unsigned i=0; i<designator.size(); i++) { unsigned index=designator[i].index; const typet &type=designator[i].type; assert(type.id()!=ID_symbol); if(type.id()==ID_array || type.id()==ID_struct || type.id()==ID_incomplete_array) { if(index>=dest->operands().size()) { if(type.id()==ID_incomplete_array) { exprt zero=zero_initializer(type.subtype(), value.location()); dest->operands().resize(integer2long(index)+1, zero); } else { err_location(value); str << "index designator " << index << " out of bounds (" << dest->operands().size() << ")"; throw 0; } } dest=&(dest->operands()[integer2long(index)]); } else if(type.id()==ID_union) { // union initialization is quite special const union_typet &union_type=to_union_type(type); const union_typet::componentt &component=union_type.components()[index]; // build a union expression from the argument exprt union_expr(ID_union, type); union_expr.operands().resize(1); union_expr.op0()=zero_initializer(component.type(), value.location()); union_expr.location()=value.location(); union_expr.set(ID_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 typet type=follow(designator.back().subtype); assert(type.id()!=ID_symbol); // do we initialize a scalar? if(type.id()!=ID_struct && type.id()!=ID_union && type.id()!=ID_array && type.id()!=ID_incomplete_array) { // 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(type==follow(dest->type())); return; // done } // 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((type.id()==ID_array || type.id()==ID_incomplete_array) && (follow(type.subtype()).id()==ID_signedbv || follow(type.subtype()).id()==ID_unsignedbv)) { *dest=do_initializer_rec(value, type, force_constant); return; // done } } else if(follow(value.type())==type) { // a struct/union can be initialized directly with // an expression of the right type. This doesn't // work with arrays, unfortunately. if(type.id()==ID_struct || type.id()==ID_union) { *dest=value; return; // done } } // we are initializing a compound type, and enter it! designator_enter(type, designator); assert(!dest->operands().empty()); dest=&(dest->op0()); // we run into another loop iteration } }