void c_typecheck_baset::designator_enter( const typet &type, designatort &designator) { designatort::entryt entry; entry.type=type; assert(entry.type.id()!=ID_symbol); if(entry.type.id()==ID_struct) { entry.size=to_struct_type(entry.type).components().size(); if(entry.size!=0) entry.subtype=to_struct_type(entry.type).components().front().type(); else entry.subtype.make_nil(); } else if(entry.type.id()==ID_union) { if(to_union_type(entry.type).components().empty()) { entry.size=0; entry.subtype.make_nil(); } else { entry.size=1; entry.subtype=to_union_type(entry.type).components().front().type(); } } else if(entry.type.id()==ID_array) { mp_integer array_size; if(to_integer(to_array_type(entry.type).size(), array_size)) { err_location(to_array_type(entry.type).size()); str << "array has non-constant size `" << to_string(to_array_type(entry.type).size()) << "'"; throw 0; } entry.size=integer2long(array_size); entry.subtype=entry.type.subtype(); } else if(entry.type.id()==ID_incomplete_array) { entry.size=0; entry.subtype=entry.type.subtype(); } else assert(false); designator.push_entry(entry); }
bool refined_string_typet::is_c_string_type(const typet &type) { if (type.id() == ID_struct) { irep_idt tag = to_struct_type(type).get_tag(); return (tag == irep_idt("__CPROVER_string")); } else return false; }
void java_root_class(symbolt &class_symbol) { struct_typet &struct_type=to_struct_type(class_symbol.type); struct_typet::componentst &components=struct_type.components(); { // for monitorenter/monitorexit struct_typet::componentt component; component.set_name("@lock"); component.set_pretty_name("@lock"); component.type()=java_boolean_type(); // add at the beginning components.insert(components.begin(), component); } { // the class identifier is used for stuff such as 'instanceof' struct_typet::componentt component; component.set_name("@class_identifier"); component.set_pretty_name("@class_identifier"); component.type()=string_typet(); // add at the beginning components.insert(components.begin(), component); } }
void java_bytecode_parsert::get_class_refs_rec(const typet &src) { if(src.id()==ID_code) { const code_typet &ct=to_code_type(src); const typet &rt=ct.return_type(); get_class_refs_rec(rt); for(const auto &p : ct.parameters()) get_class_refs_rec(p.type()); } else if(src.id()==ID_symbol) { irep_idt name=src.get(ID_C_base_name); if(has_prefix(id2string(name), "array[")) { const typet &element_type= static_cast<const typet &>(src.find(ID_C_element_type)); get_class_refs_rec(element_type); } else parse_tree.class_refs.insert(name); } else if(src.id()==ID_struct) { const struct_typet &struct_type=to_struct_type(src); for(const auto &c : struct_type.components()) get_class_refs_rec(c.type()); } else if(src.id()==ID_pointer) get_class_refs_rec(src.subtype()); }
bvt boolbvt::convert_struct(const struct_exprt &expr) { const struct_typet &struct_type=to_struct_type(ns.follow(expr.type())); std::size_t width=boolbv_width(struct_type); const struct_typet::componentst &components=struct_type.components(); if(expr.operands().size()!=components.size()) { error().source_location=expr.find_source_location(); error() << "struct: wrong number of arguments" << eom; throw 0; } bvt bv; bv.resize(width); std::size_t offset=0, i=0; for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { const typet &subtype=it->type(); const exprt &op=expr.operands()[i]; if(!base_type_eq(subtype, op.type(), ns)) { error().source_location=expr.find_source_location(); error() << "struct: component type does not match: " << subtype.pretty() << " vs. " << op.type().pretty() << eom; throw 0; } std::size_t subtype_width=boolbv_width(subtype); if(subtype_width!=0) { const bvt &op_bv=convert_bv(op); assert(offset<width); assert(op_bv.size()==subtype_width); assert(offset+op_bv.size()<=width); for(std::size_t j=0; j<op_bv.size(); j++) bv[offset+j]=op_bv[j]; offset+=op_bv.size(); } i++; } assert(offset==width); return bv; }
exprt remove_virtual_functionst::build_class_identifier( const exprt &src) { // the class identifier is in the root class exprt e=src; while(1) { const typet &type=ns.follow(e.type()); assert(type.id()==ID_struct); const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components=struct_type.components(); assert(!components.empty()); member_exprt member_expr( e, components.front().get_name(), components.front().type()); if(components.front().get_name()=="@class_identifier") { // found it return member_expr; } else { e=member_expr; } } }
void boolbvt::convert_with( const typet &type, const exprt &op1, const exprt &op2, const bvt &prev_bv, bvt &next_bv) { // we only do that on arrays, bitvectors, structs, and unions next_bv.resize(prev_bv.size()); if(type.id()==ID_array) return convert_with_array(to_array_type(type), op1, op2, prev_bv, next_bv); else if(type.id()==ID_bv || type.id()==ID_unsignedbv || type.id()==ID_signedbv) return convert_with_bv(type, op1, op2, prev_bv, next_bv); else if(type.id()==ID_struct) return convert_with_struct(to_struct_type(type), op1, op2, prev_bv, next_bv); else if(type.id()==ID_union) return convert_with_union(to_union_type(type), op1, op2, prev_bv, next_bv); else if(type.id()==ID_symbol) return convert_with(ns.follow(type), op1, op2, prev_bv, next_bv); error().source_location=type.source_location(); error() << "unexpected with type: " << type.id(); throw 0; }
void path_slicert::get_suffixes( const std::string &base, const typet &type, string_sett &s) { const irep_idt &type_id=ns.follow(type).id(); if(type_id==ID_struct || type_id==ID_union) { s.insert(base); const struct_typet &struct_type=to_struct_type(ns.follow(type)); for(struct_typet::componentst::const_iterator c_it=struct_type.components().begin(); c_it!=struct_type.components().end(); c_it++) { const typet &subtype=c_it->type(); const irep_idt &name=c_it->get(ID_name); get_suffixes(base+"."+id2string(name), subtype, s); } } else if(type_id==ID_array) { s.insert(base); get_suffixes(base+"[]", ns.follow(type).subtype(), s); } else { // no suffixes s.insert(base); } }
bool refined_string_typet::is_java_deref_string_type(const typet &type) { if(type.id() == ID_struct) { irep_idt tag = to_struct_type(type).get_tag(); return (tag == irep_idt("java.lang.String")); } else return false; }
exprt remove_const_function_pointerst::get_component_value( const struct_exprt &struct_expr, const member_exprt &member_expr) { const struct_typet &struct_type=to_struct_type(ns.follow(struct_expr.type())); size_t component_number= struct_type.component_number(member_expr.get_component_name()); return struct_expr.operands()[component_number]; }
bool is_jsa_heap(const typet &type) { const irep_idt &type_id=type.id(); if (ID_symbol == type_id) return id2string(to_symbol_type(type).get_identifier()) == JSA_HEAP_TAG; if (ID_struct != type_id) return false; const irep_idt tag(to_struct_type(type).get_tag()); return id2string(tag) == JSA_HEAP_TAG; }
const exprt &get_controller_comp(const namespacet &ns, const struct_exprt &value, const char * const comp) { const struct_typet &type=to_struct_type(ns.follow(value.type())); const struct_typet::componentst &comps=type.components(); for (size_t i=0; i < comps.size(); ++i) if (id2string(comps[i].get_name()) == comp) return value.operands()[i]; assert(!"Solution component not found."); }
const struct_typet &cpp_typecheckt::this_struct_type() { const exprt &this_expr = cpp_scopes.current_scope().this_expr; assert(this_expr.is_not_nil()); assert(this_expr.type().id() == "pointer"); const typet &t = follow(this_expr.type().subtype()); return to_struct_type(t); }
bool dereferencet::type_compatible( const typet &object_type, const typet &dereference_type) const { if(dereference_type.id()==ID_empty) return true; // always ok if(base_type_eq(object_type, dereference_type, ns)) return true; // ok, they just match // check for struct prefixes if(object_type.id()==ID_struct && dereference_type.id()==ID_struct) { if(to_struct_type(dereference_type).is_prefix_of( to_struct_type(object_type))) return true; // ok, dreference_type is a prefix of object_type } // any code is ok if(dereference_type.id()==ID_code && object_type.id()==ID_code) return true; // bit vectors of same size are ok if((object_type.id()==ID_signedbv || object_type.id()==ID_unsignedbv) && (dereference_type.id()==ID_signedbv || dereference_type.id()==ID_unsignedbv)) { return object_type.get(ID_width)==dereference_type.get(ID_width); } // Any pointer to pointer is always ok, // but should likely check that width is the same. if(object_type.id()==ID_pointer && dereference_type.id()==ID_pointer) return true; // really different return false; }
void cpp_typecheckt::find_constructor( const typet &start_dest_type, exprt &constructor_expr) { constructor_expr.make_nil(); source_locationt source_location=start_dest_type.source_location(); typet dest_type(start_dest_type); follow_symbol(dest_type); if(dest_type.id()!=ID_struct) return; const struct_typet::componentst &components= to_struct_type(dest_type).components(); for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { const struct_typet::componentt &component=*it; const typet &type=component.type(); if(type.find(ID_return_type).id()==ID_constructor) { const irept::subt ¶meters= type.find(ID_parameters).get_sub(); namespacet ns(symbol_table); if(parameters.size()==1) { const exprt ¶meter=(exprt &)parameters.front(); const typet &arg_type=parameter.type(); if(arg_type.id()==ID_pointer && type_eq(arg_type.subtype(), dest_type, ns)) { // found! const irep_idt &identifier= component.get(ID_name); if(identifier=="") throw "constructor without identifier"; constructor_expr=exprt(ID_symbol, type); constructor_expr.set(ID_identifier, identifier); constructor_expr.add_source_location()=source_location; return; } } } } }
bool value_set_dereferencet::dereference_type_compare( const typet &object_type, const typet &dereference_type) const { if(dereference_type.id()==ID_empty) return true; // always ok if(base_type_eq(object_type, dereference_type, ns)) return true; // ok, they just match // check for struct prefixes const typet ot_base=ns.follow(object_type), dt_base=ns.follow(dereference_type); if(ot_base.id()==ID_struct && dt_base.id()==ID_struct) { if(to_struct_type(dt_base).is_prefix_of( to_struct_type(ot_base))) return true; // ok, dt is a prefix of ot } // we are generous about code pointers if(dereference_type.id()==ID_code && object_type.id()==ID_code) return true; // bitvectors of same width are ok if((dereference_type.id()==ID_signedbv || dereference_type.id()==ID_unsignedbv) && (object_type.id()==ID_signedbv || object_type.id()==ID_unsignedbv) && to_bitvector_type(dereference_type).get_width()== to_bitvector_type(object_type).get_width()) return true; // really different return false; }
bool refined_string_typet::is_java_char_sequence_type(const typet &type) { if(type.id() == ID_pointer) { pointer_typet pt = to_pointer_type(type); typet subtype = pt.subtype(); if(subtype.id() == ID_struct) { irep_idt tag = to_struct_type(subtype).get_tag(); return (tag == irep_idt("java.lang.CharSequence")); } else return false; } else return false; }
mp_integer compute_pointer_offset( const namespacet &ns, const exprt &expr) { if(expr.id()==ID_symbol) return 0; else if(expr.id()==ID_index) { assert(expr.operands().size()==2); const typet &array_type=ns.follow(expr.op0().type()); assert(array_type.id()==ID_array); mp_integer o=compute_pointer_offset(ns, expr.op0()); if(o!=-1) { mp_integer sub_size= pointer_offset_size(ns, array_type.subtype()); mp_integer i; if(sub_size!=0 && !to_integer(expr.op1(), i)) return o+i*sub_size; } // don't know } else if(expr.id()==ID_member) { assert(expr.operands().size()==1); const typet &type=ns.follow(expr.op0().type()); assert(type.id()==ID_struct || type.id()==ID_union); mp_integer o=compute_pointer_offset(ns, expr.op0()); if(o!=-1) { if(type.id()==ID_union) return o; return o+member_offset( ns, to_struct_type(type), expr.get(ID_component_name)); } } else if(expr.id()==ID_string_constant) return 0; return -1; // don't know }
/// \par parameters: a type /// \return Boolean telling whether the type is that of java char sequence bool refined_string_typet::is_java_char_sequence_type(const typet &type) { if(type.id()==ID_pointer) { const pointer_typet &pt=to_pointer_type(type); const typet &subtype=pt.subtype(); if(subtype.id()==ID_struct) { const irep_idt &tag=to_struct_type(subtype).get_tag(); return tag=="java.lang.CharSequence"; } } return false; }
/// \par parameters: a type /// \return Boolean telling whether the type is that of java string builder bool refined_string_typet::is_java_string_builder_type(const typet &type) { if(type.id()==ID_pointer) { const pointer_typet &pt=to_pointer_type(type); const typet &subtype=pt.subtype(); if(subtype.id()==ID_struct) { irep_idt tag=to_struct_type(subtype).get_tag(); return tag=="java.lang.StringBuilder"; } } return false; }
/// \par parameters: a type /// \return Boolean telling whether the type is that of java string bool refined_string_typet::is_java_string_type(const typet &type) { if(type.id()==ID_symbol) { irep_idt tag=to_symbol_type(type).get_identifier(); return tag=="java::java.lang.String"; } else if(type.id()==ID_struct) { irep_idt tag=to_struct_type(type).get_tag(); return tag=="java.lang.String"; } return false; }
void c_typecheck_baset::increment_designator(designatort &designator) { assert(!designator.empty()); while(true) { designatort::entryt &entry=designator[designator.size()-1]; const typet &full_type=follow(entry.type); entry.index++; if(full_type.id()==ID_array && to_array_type(full_type).size().is_nil()) return; // we will keep going forever if(full_type.id()==ID_struct && entry.index<entry.size) { // need to adjust subtype const struct_typet &struct_type= to_struct_type(full_type); const struct_typet::componentst &components= struct_type.components(); assert(components.size()==entry.size); // we skip over any padding or code while(entry.index<entry.size && (components[entry.index].get_is_padding() || components[entry.index].type().id()==ID_code)) entry.index++; if(entry.index<entry.size) entry.subtype=components[entry.index].type(); } if(entry.index<entry.size) return; // done if(designator.size()==1) return; // done // pop entry designator.pop_entry(); assert(!designator.empty()); } }
code_function_callt get_destructor( const namespacet &ns, const typet &type) { if(type.id()==ID_symbol) { return get_destructor(ns, ns.follow(type)); } else if(type.id()==ID_struct) { const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components= struct_type.components(); for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { if(it->type().id()==ID_code) { const code_typet &code_type=to_code_type(it->type()); if(code_type.return_type().id()==ID_destructor && code_type.parameters().size()==1) { const typet &arg_type=code_type.parameters().front().type(); if(arg_type.id()==ID_pointer && ns.follow(arg_type.subtype())==type) { exprt symbol_expr(ID_symbol, it->type()); symbol_expr.set(ID_identifier, it->get(ID_name)); code_function_callt function_call; function_call.function()=symbol_expr; return function_call; } } } } } return static_cast<const code_function_callt &>(get_nil_irep()); }
bool replace_symbolt::replace(typet &dest) { if(dest.has_subtype()) replace(dest.subtype()); Forall_subtypes(it, dest) replace(*it); if(dest.id()=="struct" || dest.id()=="union") { struct_typet &struct_type = to_struct_type(dest); struct_typet::componentst &components = struct_type.components(); for (struct_typet::componentst::iterator it = components.begin(); it!=components.end(); it++) replace(*it); } else if(dest.is_code()) { code_typet &code_type=to_code_type(dest); code_typet::argumentst &arguments=code_type.arguments(); for (code_typet::argumentst::iterator it = arguments.begin(); it!=arguments.end(); it++) replace(*it); } if(dest.id()=="symbol") { type_mapt::const_iterator it= type_map.find(dest.identifier()); if(it!=type_map.end()) { dest=it->second; return false; } } return true; }
void cpp_typecheckt::clean_up() { context.Foreach_operand([this](symbolt &s) { if(s.type.get_bool("is_template")) { context.erase_symbol(s.name); return; } if(s.type.is_struct() || s.type.is_union()) { struct_typet &struct_type = to_struct_type(s.type); const struct_typet::componentst &components = struct_type.components(); struct_typet::componentst data_members; data_members.reserve(components.size()); struct_typet::componentst &function_members = struct_type.methods(); function_members.reserve(components.size()); for(const auto &component : components) { if(component.get_bool("is_static") || component.is_type()) { // skip it } else if(component.type().id() == "code") { function_members.push_back(component); } else { data_members.push_back(component); } } struct_type.components().swap(data_members); } }); }
void c_typecheck_baset::increment_designator(designatort &designator) { assert(!designator.empty()); while(true) { designatort::entryt &entry=designator[designator.size()-1]; entry.index++; if(entry.type.id()==ID_incomplete_array) return; // we will keep going forever if(entry.type.id()==ID_struct && entry.index<entry.size) { // need to adjust subtype const struct_typet &struct_type= to_struct_type(entry.type); const struct_typet::componentst &components= struct_type.components(); assert(components.size()==entry.size); // we skip over padding if(components[entry.index].get_is_padding()) entry.index++; if(entry.index<entry.size) entry.subtype=components[entry.index].type(); } if(entry.index<entry.size) return; // done if(designator.size()==1) return; // done // pop entry designator.pop_entry(); assert(!designator.empty()); } }
void set_class_identifier( struct_exprt &expr, const namespacet &ns, const symbol_typet &class_type) { const struct_typet &struct_type= to_struct_type(ns.follow(expr.type())); const struct_typet::componentst &components=struct_type.components(); if(components.empty()) return; assert(!expr.operands().empty()); if(components.front().get_name()=="@class_identifier") { assert(expr.op0().id()==ID_constant); expr.op0()=constant_exprt(class_type.get_identifier(), string_typet()); } else { assert(expr.op0().id()==ID_struct); set_class_identifier(to_struct_expr(expr.op0()), ns, class_type); } }
void invariant_propagationt::get_objects_rec( const exprt &src, std::list<exprt> &dest) { const typet &t=ns.follow(src.type()); if(t.id()==ID_struct || t.id()==ID_union) { const struct_typet &struct_type=to_struct_type(t); const struct_typet::componentst &c=struct_type.components(); exprt member_expr(ID_member); member_expr.copy_to_operands(src); for(struct_typet::componentst::const_iterator it=c.begin(); it!=c.end(); it++) { member_expr.set(ID_component_name, it->get_string(ID_name)); member_expr.type()=it->type(); // recursive call get_objects_rec(member_expr, dest); } } else if(t.id()==ID_array) { //get_objects_rec(identifier, suffix+"[]", t.subtype(), dest); //we don't track these } else if(check_type(t)) { dest.push_back(src); } }
void value_set_analysis_fivrt::get_entries_rec( const irep_idt &identifier, const std::string &suffix, const typet &type, std::list<value_set_fivrt::entryt> &dest) { const typet &t=ns.follow(type); if(t.id()==ID_struct || t.id()==ID_union) { const struct_typet &struct_type=to_struct_type(t); const struct_typet::componentst &c=struct_type.components(); for(struct_typet::componentst::const_iterator it=c.begin(); it!=c.end(); it++) { get_entries_rec( identifier, suffix+"."+it->get_string(ID_name), it->type(), dest); } } else if(t.id()==ID_array) { get_entries_rec(identifier, suffix+"[]", t.subtype(), dest); } else if(check_type(t)) { dest.push_back(value_set_fivrt::entryt(identifier, suffix)); } }
#include <util/std_types.h> #include <util/symbol_table.h> /// Looks for all the struct types in the symbol table and construct a map from /// class names to a data structure that contains lists of parent and child /// classes for each struct type (ie class). /// \param symbol_table: The symbol table to analyze void class_hierarchyt::operator()(const symbol_tablet &symbol_table) { forall_symbols(it, symbol_table.symbols) { if(it->second.is_type && it->second.type.id()==ID_struct) { const struct_typet &struct_type= to_struct_type(it->second.type); const irept::subt &bases= struct_type.find(ID_bases).get_sub(); for(const auto &base : bases) { irep_idt parent=base.find(ID_type).get(ID_identifier); if(parent.empty()) continue; class_map[parent].children.push_back(it->first); class_map[it->first].parents.push_back(parent); } } }