void c_typecheck_baset::typecheck_symbol_type(typet &type) { { // add prefix symbol_typet &symbol_type=to_symbol_type(type); symbol_type.set_identifier(add_language_prefix(symbol_type.get_identifier())); } // adjust identifier, if needed replace_symbol(type); const irep_idt &identifier= to_symbol_type(type).get_identifier(); symbol_tablet::symbolst::const_iterator s_it= symbol_table.symbols.find(identifier); if(s_it==symbol_table.symbols.end()) { err_location(type); str << "type symbol `" << identifier << "' not found"; throw 0; } const symbolt &symbol=s_it->second; if(!symbol.is_type) { err_location(type); throw "expected type symbol"; } if(symbol.is_macro) { // overwrite, but preserve (add) any qualifiers and other flags c_qualifierst c_qualifiers(type); bool is_packed=type.get_bool(ID_C_packed); irept alignment=type.find(ID_C_alignment); c_qualifiers+=c_qualifierst(symbol.type); type=symbol.type; c_qualifiers.write(type); if(is_packed) type.set(ID_C_packed, true); if(alignment.is_not_nil()) type.set(ID_C_alignment, alignment); } // CPROVER extensions if(symbol.base_name=="__CPROVER_rational") { type=rational_typet(); } else if(symbol.base_name=="__CPROVER_integer") { type=integer_typet(); } }
void java_bytecode_convertt::add_array_types() { const char letters[]="ijsbcfdza"; for(unsigned i=0; letters[i]!=0; i++) { symbol_typet symbol_type= to_symbol_type(java_array_type(letters[i]).subtype()); struct_typet struct_type; // we have the base class, java.lang.Object, length and data // of appropriate type struct_type.set_tag(symbol_type.get_identifier()); struct_type.components().resize(3); struct_type.components()[0].set_name("@java.lang.Object"); struct_type.components()[0].type()=symbol_typet("java::java.lang.Object"); struct_type.components()[1].set_name("length"); struct_type.components()[1].type()=java_int_type(); struct_type.components()[2].set_name("data"); struct_type.components()[2].type()= pointer_typet(java_type_from_char(letters[i])); symbolt symbol; symbol.name=symbol_type.get_identifier(); symbol.base_name=symbol_type.get(ID_C_base_name); symbol.is_type=true; symbol.type=struct_type; symbol_table.add(symbol); } }
void linkingt::rename_type_symbol(symbolt &new_symbol) { replace_symbolt::type_mapt::const_iterator replace_entry= replace_symbol.type_map.find(new_symbol.name); if(replace_entry!=replace_symbol.type_map.end()) { new_symbol.name=to_symbol_type(replace_entry->second).get_identifier(); } else { // rename! irep_idt old_identifier=new_symbol.name; irep_idt new_identifier=rename(old_identifier); replace_symbol.insert(old_identifier, symbol_typet(new_identifier)); new_symbol.name=new_identifier; } // need to replace again replace_symbol.replace(new_symbol.type); // move over! bool result=main_context.move(new_symbol); assert(!result); }
void java_bytecode_convert_classt::add_array_types() { const std::string letters="ijsbcfdza"; for(const char l : letters) { symbol_typet symbol_type= to_symbol_type(java_array_type(l).subtype()); struct_typet struct_type; // we have the base class, java.lang.Object, length and data // of appropriate type struct_type.set_tag(symbol_type.get_identifier()); struct_type.components().reserve(3); struct_typet::componentt comp0("@java.lang.Object", symbol_typet("java::java.lang.Object")); struct_type.components().push_back(comp0); struct_typet::componentt comp1("length", java_int_type()); struct_type.components().push_back(comp1); struct_typet::componentt comp2("data", pointer_typet(java_type_from_char(l))); struct_type.components().push_back(comp2); symbolt symbol; symbol.name=symbol_type.get_identifier(); symbol.base_name=symbol_type.get(ID_C_base_name); symbol.is_type=true; symbol.type=struct_type; symbol_table.add(symbol); } }
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; }
/// \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 goto_convertt::do_java_new( const exprt &lhs, const side_effect_exprt &rhs, goto_programt &dest) { if(lhs.is_nil()) throw "do_java_new without lhs is yet to be implemented"; source_locationt location=rhs.source_location(); assert(rhs.operands().empty()); if(rhs.type().id()!=ID_pointer) throw "do_java_new returns pointer"; typet object_type=rhs.type().subtype(); // build size expression exprt object_size=size_of_expr(object_type, ns); if(object_size.is_nil()) throw "do_java_new got nil object_size"; // we produce a malloc side-effect, which stays side_effect_exprt malloc_expr(ID_malloc); malloc_expr.copy_to_operands(object_size); malloc_expr.type()=pointer_typet(object_type); goto_programt::targett t_n=dest.add_instruction(ASSIGN); t_n->code=code_assignt(lhs, malloc_expr); t_n->source_location=location; // zero-initialize the object dereference_exprt deref(lhs, object_type); exprt zero_object=zero_initializer(object_type, location, ns, get_message_handler()); set_class_identifier(to_struct_expr(zero_object), ns, to_symbol_type(object_type)); goto_programt::targett t_i=dest.add_instruction(ASSIGN); t_i->code=code_assignt(deref, zero_object); t_i->source_location=location; }
void java_bytecode_typecheckt::typecheck_type(typet &type) { if(type.id()==ID_symbol) { irep_idt identifier=to_symbol_type(type).get_identifier(); symbol_tablet::symbolst::const_iterator s_it= symbol_table.symbols.find(identifier); // must exist already in the symbol table if(s_it==symbol_table.symbols.end()) { error() << "failed to find type symbol "<< identifier << eom; throw 0; } assert(s_it->second.is_type); } else if(type.id()==ID_pointer) { typecheck_type(type.subtype()); } else if(type.id()==ID_array) { typecheck_type(type.subtype()); typecheck_expr(to_array_type(type).size()); } else if(type.id()==ID_code) { code_typet &code_type=to_code_type(type); typecheck_type(code_type.return_type()); code_typet::parameterst ¶meters=code_type.parameters(); for(code_typet::parameterst::iterator it=parameters.begin(); it!=parameters.end(); it++) typecheck_type(it->type()); } }
const symbol_typet &control_solution_type(const symbol_tablet &st) { return to_symbol_type(st.lookup(CEGIS_CONTROL_SOLUTION_VAR_NAME).type); }
void c_typecheck_baset::typecheck_redefinition_non_type( symbolt &old_symbol, symbolt &new_symbol) { const typet &final_old=follow(old_symbol.type); const typet &initial_new=follow(new_symbol.type); if(final_old.id()==ID_array && to_array_type(final_old).size().is_not_nil() && initial_new.id()==ID_array && to_array_type(initial_new).size().is_nil() && final_old.subtype()==initial_new.subtype()) { // this is ok, just use old type new_symbol.type=old_symbol.type; } // do initializer, this may change the type if(follow(new_symbol.type).id()!=ID_code) do_initializer(new_symbol); const typet &final_new=follow(new_symbol.type); // K&R stuff? if(old_symbol.type.id()==ID_KnR) { // check the type if(final_new.id()==ID_code) { err_location(new_symbol.location); throw "function type not allowed for K&R function parameter"; } // fix up old symbol -- we now got the type old_symbol.type=new_symbol.type; return; } if(final_new.id()==ID_code) { bool inlined= (new_symbol.type.get_bool(ID_C_inlined) || old_symbol.type.get_bool(ID_C_inlined)); if(final_old.id()!=ID_code) { err_location(new_symbol.location); str << "error: function symbol `" << new_symbol.display_name() << "' redefined with a different type:" << "\n"; str << "Original: " << to_string(old_symbol.type) << "\n"; str << " New: " << to_string(new_symbol.type); throw 0; } code_typet &old_ct=to_code_type(old_symbol.type); code_typet &new_ct=to_code_type(new_symbol.type); if(old_ct.has_ellipsis() && !new_ct.has_ellipsis()) old_ct=new_ct; else if(!old_ct.has_ellipsis() && new_ct.has_ellipsis()) new_ct=old_ct; if(inlined) { old_symbol.type.set(ID_C_inlined, true); new_symbol.type.set(ID_C_inlined, true); } // do body if(new_symbol.value.is_not_nil()) { if(old_symbol.value.is_not_nil()) { // gcc allows re-definition if the first // definition is marked as "extern inline" if(old_symbol.type.get_bool(ID_C_inlined) && (config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_GCC_C || config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_ARM_C_CPP)) { // overwrite "extern inline" properties old_symbol.is_extern=new_symbol.is_extern; old_symbol.is_file_local=new_symbol.is_file_local; // remove parameter declarations to avoid conflicts const code_typet::parameterst &old_p=old_ct.parameters(); for(code_typet::parameterst::const_iterator p_it=old_p.begin(); p_it!=old_p.end(); p_it++) { const irep_idt &identifier=p_it->get_identifier(); symbol_tablet::symbolst::iterator p_s_it= symbol_table.symbols.find(identifier); if(p_s_it!=symbol_table.symbols.end()) symbol_table.symbols.erase(p_s_it); } } else { err_location(new_symbol.location); str << "function body `" << new_symbol.display_name() << "' defined twice"; error_msg(); throw 0; } } else if(inlined) { // preserve "extern inline" properties old_symbol.is_extern=new_symbol.is_extern; old_symbol.is_file_local=new_symbol.is_file_local; } typecheck_function_body(new_symbol); // overwrite location old_symbol.location=new_symbol.location; // move body old_symbol.value.swap(new_symbol.value); // overwrite type (because of parameter names) old_symbol.type=new_symbol.type; } return; } if(final_old!=final_new) { if(final_old.id()==ID_array && to_array_type(final_old).size().is_nil() && final_new.id()==ID_array && to_array_type(final_new).size().is_not_nil() && final_old.subtype()==final_new.subtype()) { // this is also ok if(old_symbol.type.id()==ID_symbol) { // fix the symbol, not just the type const irep_idt identifier= to_symbol_type(old_symbol.type).get_identifier(); symbol_tablet::symbolst::iterator s_it=symbol_table.symbols.find(identifier); if(s_it==symbol_table.symbols.end()) { err_location(old_symbol.location); str << "typecheck_redefinition_non_type: " "failed to find symbol `" << identifier << "'"; throw 0; } symbolt &symbol=s_it->second; symbol.type=final_new; } else old_symbol.type=new_symbol.type; } else if((final_old.id()==ID_incomplete_c_enum || final_old.id()==ID_c_enum) && (final_new.id()==ID_incomplete_c_enum || final_new.id()==ID_c_enum)) { // this is ok for now } else if(final_old.id()==ID_pointer && follow(final_old).subtype().id()==ID_code && to_code_type(follow(final_old).subtype()).has_ellipsis() && final_new.id()==ID_pointer && follow(final_new).subtype().id()==ID_code) { // to allow // int (*f) (); // int (*f) (int)=0; old_symbol.type=new_symbol.type; } else if(final_old.id()==ID_pointer && follow(final_old).subtype().id()==ID_code && final_new.id()==ID_pointer && follow(final_new).subtype().id()==ID_code && to_code_type(follow(final_new).subtype()).has_ellipsis()) { // to allow // int (*f) (int)=0; // int (*f) (); } else { err_location(new_symbol.location); str << "error: symbol `" << new_symbol.display_name() << "' redefined with a different type:" << "\n"; str << "Original: " << to_string(old_symbol.type) << "\n"; str << " New: " << to_string(new_symbol.type); throw 0; } } else // finals are equal { } // do value if(new_symbol.value.is_not_nil()) { // see if we already have one if(old_symbol.value.is_not_nil()) { if(new_symbol.value.get_bool(ID_C_zero_initializer)) { // do nothing } else if(old_symbol.value.get_bool(ID_C_zero_initializer)) { old_symbol.value=new_symbol.value; old_symbol.type=new_symbol.type; } else { if(new_symbol.is_macro && (final_new.id()==ID_incomplete_c_enum || final_new.id()==ID_c_enum) && old_symbol.value.is_constant() && new_symbol.value.is_constant() && old_symbol.value.get(ID_value)==new_symbol.value.get(ID_value)) { // ignore } else { err_location(new_symbol.value); str << "symbol `" << new_symbol.display_name() << "' already has an initial value"; warning_msg(); } } } else { old_symbol.value=new_symbol.value; old_symbol.type=new_symbol.type; } } // take care of some flags if(old_symbol.is_extern && !new_symbol.is_extern) old_symbol.location=new_symbol.location; old_symbol.is_extern=old_symbol.is_extern && new_symbol.is_extern; // We should likely check is_volatile and // is_thread_local for consistency. GCC complains if these // mismatch. }
void c_typecheck_baset::clean_type( const irep_idt &base_symbol_identifier, typet &type, std::list<codet> &code) { if(type.id()==ID_symbol) { // we need to follow for structs and such, but only once irep_idt identifier=to_symbol_type(type).get_identifier(); if(already_cleaned.insert(identifier).second) { symbol_tablet::symbolst::iterator s_it=symbol_table.symbols.find(identifier); assert(s_it!=symbol_table.symbols.end()); clean_type(identifier, s_it->second.type, code); } } else if(type.id()==ID_array) { array_typet &array_type=to_array_type(type); clean_type(base_symbol_identifier, array_type.subtype(), code); // The size need not be a constant! // This was simplified already by typecheck_array_type. exprt &size=array_type.size(); if(size.is_not_nil() && !size.is_constant() && size.id()!=ID_infinity && !(size.id()==ID_symbol && size.type().get_bool(ID_C_constant))) { // The criterion above can be tricked: // Of course we can modify a 'const' symbol, e.g., // using a pointer type cast. Interestingly, // at least gcc 4.2.1 makes the very same mistake! assert(current_symbol_id!=irep_idt()); const symbolt &base_symbol= lookup( base_symbol_identifier!=irep_idt()? base_symbol_identifier: current_symbol_id); // Need to pull out! We insert new symbol. locationt location=size.find_location(); unsigned count=0; irep_idt temp_identifier; std::string suffix; do { suffix="$array_size"+i2string(count); temp_identifier=id2string(base_symbol.name)+suffix; count++; } while(symbol_table.symbols.find(temp_identifier)!=symbol_table.symbols.end()); // add the symbol to symbol table symbolt new_symbol; new_symbol.name=temp_identifier; new_symbol.pretty_name=id2string(base_symbol.pretty_name)+suffix; new_symbol.base_name=id2string(base_symbol.base_name)+suffix; new_symbol.type=size.type(); new_symbol.type.set(ID_C_constant, true); new_symbol.is_file_local=true; new_symbol.is_type=false; new_symbol.is_thread_local=true; new_symbol.is_static_lifetime=false; new_symbol.value.make_nil(); new_symbol.location=location; symbol_table.add(new_symbol); // produce the code that declares and initializes the symbol symbol_exprt symbol_expr; symbol_expr.set_identifier(temp_identifier); symbol_expr.type()=new_symbol.type; code_declt declaration(symbol_expr); declaration.location()=location; code_assignt assignment; assignment.lhs()=symbol_expr; assignment.rhs()=size; assignment.location()=location; // store the code code.push_back(declaration); code.push_back(assignment); // fix type size=symbol_expr; } } else if(type.id()==ID_struct || type.id()==ID_union) { struct_union_typet::componentst &components= to_struct_union_type(type).components(); for(struct_union_typet::componentst::iterator it=components.begin(); it!=components.end(); it++) clean_type(base_symbol_identifier, it->type(), code); } else if(type.id()==ID_code) { // done, can't contain arrays } else if(type.id()==ID_pointer) { clean_type(base_symbol_identifier, type.subtype(), code); } else if(type.id()==ID_vector) { // should be clean } }
void java_bytecode_parsert::rmethod_attribute(methodt &method) { u2 attribute_name_index=read_u2(); u4 attribute_length=read_u4(); irep_idt attribute_name=pool_entry(attribute_name_index).s; if(attribute_name=="Code") { u2 UNUSED max_stack=read_u2(); u2 UNUSED max_locals=read_u2(); rbytecode(method.instructions); u2 exception_table_length=read_u2(); method.exception_table.resize(exception_table_length); for(std::size_t e=0; e<exception_table_length; e++) { u2 start_pc=read_u2(); u2 end_pc=read_u2(); u2 handler_pc=read_u2(); u2 catch_type=read_u2(); method.exception_table[e].start_pc=start_pc; method.exception_table[e].end_pc=end_pc; method.exception_table[e].handler_pc=handler_pc; if(catch_type!=0) method.exception_table[e].catch_type= to_symbol_type(pool_entry(catch_type).expr.type()); } u2 attributes_count=read_u2(); for(std::size_t j=0; j<attributes_count; j++) rcode_attribute(method); irep_idt line_number; // add missing line numbers for(methodt::instructionst::iterator it=method.instructions.begin(); it!=method.instructions.end(); it++) { if(!it->source_location.get_line().empty()) line_number=it->source_location.get_line(); else if(!line_number.empty()) it->source_location.set_line(line_number); it->source_location .set_function( "java::"+id2string(parse_tree.parsed_class.name)+"."+ id2string(method.name)+":"+method.signature); } // line number of method if(!method.instructions.empty()) method.source_location.set_line( method.instructions.begin()->source_location.get_line()); } else if(attribute_name=="RuntimeInvisibleAnnotations" || attribute_name=="RuntimeVisibleAnnotations") { rRuntimeAnnotation_attribute(method.annotations); } else skip_bytes(attribute_length); }