bool refined_string_typet::is_java_string_type(const typet &type) { if(type.id() == ID_pointer) { pointer_typet pt = to_pointer_type(type); typet subtype = pt.subtype(); return is_java_deref_string_type(subtype); } else return false; }
void base_type_rec( typet &type, const namespacet &ns, std::set<irep_idt> &symb) { if(type.id()==ID_symbol || type.id()==ID_c_enum_tag || type.id()==ID_struct_tag || type.id()==ID_union_tag) { const symbolt *symbol; if(!ns.lookup(type.get(ID_identifier), symbol) && symbol->is_type && !symbol->type.is_nil()) { type=symbol->type; base_type_rec(type, ns, symb); // recursive call return; } } else if(type.id()==ID_array) { base_type_rec(to_array_type(type).subtype(), ns, symb); } else if(type.id()==ID_struct || type.id()==ID_union) { struct_union_typet::componentst &components= to_struct_union_type(type).components(); for(auto &component : components) base_type_rec(component.type(), ns, symb); } else if(type.id()==ID_pointer) { typet &subtype=to_pointer_type(type).subtype(); // we need to avoid running into an infinite loop if(subtype.id()==ID_symbol || subtype.id()==ID_c_enum_tag || subtype.id()==ID_struct_tag || subtype.id()==ID_union_tag) { const irep_idt &id=subtype.get(ID_identifier); if(symb.find(id)!=symb.end()) return; symb.insert(id); base_type_rec(subtype, ns, symb); symb.erase(id); } else base_type_rec(subtype, ns, symb); } }
/// \par parameters: a type /// \return Boolean telling whether the type is that of java string pointers bool refined_string_typet::is_java_string_pointer_type(const typet &type) { if(type.id()==ID_pointer) { const pointer_typet &pt=to_pointer_type(type); const typet &subtype=pt.subtype(); return is_java_string_type(subtype); } return false; }
void equality_domaint::make_template( const var_specst &var_specs, const namespacet &ns) { unsigned size=var_specs.size(); // just an estimate templ.clear(); templ.reserve(size); for(var_specst::const_iterator v1=var_specs.begin(); v1!=var_specs.end(); v1++) { // NULL pointer checks if(v1->var.type().id()==ID_pointer) { templ.push_back(template_rowt()); template_rowt &templ_row=templ.back(); templ_row.var_pair= var_pairt(v1->var, null_pointer_exprt(to_pointer_type(v1->var.type()))); templ_row.pre_guard=v1->pre_guard; templ_row.post_guard=v1->post_guard; templ_row.aux_expr=v1->aux_expr; templ_row.kind=v1->kind; } var_specst::const_iterator v2=v1; v2++; for(; v2!=var_specs.end(); v2++) { kindt k=domaint::merge_kinds(v1->kind, v2->kind); #if 0 // TODO: must be done in caller (for preconditions, e.g.) if(k==IN) continue; #endif exprt pre_g, post_g, aux_expr; merge_and(pre_g, v1->pre_guard, v2->pre_guard, ns); merge_and(post_g, v1->post_guard, v2->post_guard, ns); merge_and(aux_expr, v1->aux_expr, v2->aux_expr, ns); exprt vv1=v1->var; exprt vv2=v2->var; if(!adapt_types(vv1, vv2)) continue; templ.push_back(template_rowt()); template_rowt &templ_row=templ.back(); templ_row.var_pair=var_pairt(vv1, vv2); templ_row.pre_guard=pre_g; templ_row.post_guard=post_g; templ_row.aux_expr=aux_expr; templ_row.kind=k; } } }
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; }
/// \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; }
void goto_checkt::pointer_validity_check( const dereference_exprt &expr, const guardt &guard) { if(!enable_pointer_check) return; const exprt &pointer=expr.op0(); const typet &pointer_type=to_pointer_type(ns.follow(pointer.type())); assert(base_type_eq(pointer_type.subtype(), expr.type(), ns)); local_bitvector_analysist::flagst flags= local_bitvector_analysis->get(t, pointer); const typet &dereference_type=pointer_type.subtype(); // For Java, we only need to check for null if(mode==ID_java) { if(flags.is_unknown() || flags.is_null()) { notequal_exprt not_eq_null(pointer, gen_zero(pointer.type())); add_guarded_claim( not_eq_null, "reference is null", "pointer dereference", expr.find_source_location(), expr, guard); } } else { if(flags.is_unknown() || flags.is_null()) { add_guarded_claim( not_exprt(null_pointer(pointer)), "dereference failure: pointer NULL", "pointer dereference", expr.find_source_location(), expr, guard); } if(flags.is_unknown()) add_guarded_claim( not_exprt(invalid_pointer(pointer)), "dereference failure: pointer invalid", "pointer dereference", expr.find_source_location(), expr, guard); if(flags.is_uninitialized()) add_guarded_claim( not_exprt(invalid_pointer(pointer)), "dereference failure: pointer uninitialized", "pointer dereference", expr.find_source_location(), expr, guard); if(mode != ID_java) { if(flags.is_unknown() || flags.is_dynamic_heap()) add_guarded_claim( not_exprt(deallocated(pointer, ns)), "dereference failure: deallocated dynamic object", "pointer dereference", expr.find_source_location(), expr, guard); if(flags.is_unknown() || flags.is_dynamic_local()) add_guarded_claim( not_exprt(dead_object(pointer, ns)), "dereference failure: dead object", "pointer dereference", expr.find_source_location(), expr, guard); } if(enable_bounds_check) { if(flags.is_unknown() || flags.is_dynamic_heap()) { exprt dynamic_bounds= or_exprt(dynamic_object_lower_bound(pointer), dynamic_object_upper_bound(pointer, dereference_type, ns)); add_guarded_claim( implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)), "dereference failure: dynamic object bounds", "pointer dereference", expr.find_source_location(), expr, guard); } } if(enable_bounds_check) { if(flags.is_unknown() || flags.is_dynamic_local() || flags.is_static_lifetime()) { exprt object_bounds= or_exprt(object_lower_bound(pointer), object_upper_bound(pointer, dereference_type, ns)); add_guarded_claim( or_exprt(dynamic_object(pointer), not_exprt(object_bounds)), "dereference failure: object bounds", "pointer dereference", expr.find_source_location(), expr, guard); } } } }
bool equality_domaint::adapt_types(exprt &v1, exprt &v2) { // signed, unsigned integers if((v1.type().id()==ID_signedbv || v1.type().id()==ID_unsignedbv) && (v2.type().id()==ID_signedbv || v2.type().id()==ID_unsignedbv)) { unsigned size1=0, size2=0; if(v1.type().id()==ID_signedbv) size1=to_signedbv_type(v1.type()).get_width(); if(v1.type().id()==ID_unsignedbv) size1=to_unsignedbv_type(v1.type()).get_width(); if(v2.type().id()==ID_signedbv) size2=to_signedbv_type(v2.type()).get_width(); if(v2.type().id()==ID_unsignedbv) size2=to_unsignedbv_type(v2.type()).get_width(); if(v1.type().id()==v2.type().id()) { if(size1==size2) return true; typet new_type=v1.type(); if(new_type.id()==ID_signedbv) to_signedbv_type(new_type).set_width(std::max(size1, size2)); else // if(new_type.id()==ID_unsignedbv) to_unsignedbv_type(new_type).set_width(std::max(size1, size2)); if(size1>size2) v2=typecast_exprt(v2, new_type); else v1=typecast_exprt(v1, new_type); return true; } // types are different typet new_type=signedbv_typet(std::max(size1, size2)+1); v1=typecast_exprt(v1, new_type); v2=typecast_exprt(v2, new_type); return true; } // pointer equality if(v1.type().id()==ID_pointer && v2.type().id()==ID_pointer) { if(to_pointer_type(v1.type()).subtype()== to_pointer_type(v2.type()).subtype()) return true; return false; } if(v1.id()==ID_index || v2.id()==ID_index) { #if 0 std::cout << "v1: " << v1 << std::endl; std::cout << "v2: " << v2 << std::endl; #endif // TODO: implement return false; } return false; // types incompatible }
bool base_type_eqt::base_type_eq_rec( const typet &type1, const typet &type2) { if(type1==type2) return true; #if 0 std::cout << "T1: " << type1.pretty() << std::endl; std::cout << "T2: " << type2.pretty() << std::endl; #endif // loop avoidance if((type1.id()==ID_symbol || type1.id()==ID_c_enum_tag || type1.id()==ID_struct_tag || type1.id()==ID_union_tag) && type2.id()==type1.id()) { // already in same set? if(identifiers.make_union( type1.get(ID_identifier), type2.get(ID_identifier))) return true; } if(type1.id()==ID_symbol || type1.id()==ID_c_enum_tag || type1.id()==ID_struct_tag || type1.id()==ID_union_tag) { const symbolt &symbol= ns.lookup(type1.get(ID_identifier)); if(!symbol.is_type) return false; return base_type_eq_rec(symbol.type, type2); } if(type2.id()==ID_symbol || type2.id()==ID_c_enum_tag || type2.id()==ID_struct_tag || type2.id()==ID_union_tag) { const symbolt &symbol= ns.lookup(type2.get(ID_identifier)); if(!symbol.is_type) return false; return base_type_eq_rec(type1, symbol.type); } if(type1.id()!=type2.id()) return false; if(type1.id()==ID_struct || type1.id()==ID_union) { const struct_union_typet::componentst &components1= to_struct_union_type(type1).components(); const struct_union_typet::componentst &components2= to_struct_union_type(type2).components(); if(components1.size()!=components2.size()) return false; for(unsigned i=0; i<components1.size(); i++) { const typet &subtype1=components1[i].type(); const typet &subtype2=components2[i].type(); if(!base_type_eq_rec(subtype1, subtype2)) return false; if(components1[i].get_name()!=components2[i].get_name()) return false; } return true; } else if(type1.id()==ID_incomplete_struct) { return true; } else if(type1.id()==ID_incomplete_union) { return true; } else if(type1.id()==ID_code) { const code_typet::parameterst ¶meters1= to_code_type(type1).parameters(); const code_typet::parameterst ¶meters2= to_code_type(type2).parameters(); if(parameters1.size()!=parameters2.size()) return false; for(unsigned i=0; i<parameters1.size(); i++) { const typet &subtype1=parameters1[i].type(); const typet &subtype2=parameters2[i].type(); if(!base_type_eq_rec(subtype1, subtype2)) return false; } const typet &return_type1=to_code_type(type1).return_type(); const typet &return_type2=to_code_type(type2).return_type(); if(!base_type_eq_rec(return_type1, return_type2)) return false; return true; } else if(type1.id()==ID_pointer) { return base_type_eq_rec( to_pointer_type(type1).subtype(), to_pointer_type(type2).subtype()); } else if(type1.id()==ID_array) { if(!base_type_eq_rec( to_array_type(type1).subtype(), to_array_type(type2).subtype())) return false; if(to_array_type(type1).size()!=to_array_type(type2).size()) return false; return true; } else if(type1.id()==ID_incomplete_array) { return base_type_eq_rec( to_incomplete_array_type(type1).subtype(), to_incomplete_array_type(type2).subtype()); } // the below will go away typet tmp1(type1), tmp2(type2); base_type(tmp1, ns); base_type(tmp2, ns); return tmp1==tmp2; }