本文整理汇总了C++中goto_programt::add_instruction方法的典型用法代码示例。如果您正苦于以下问题:C++ goto_programt::add_instruction方法的具体用法?C++ goto_programt::add_instruction怎么用?C++ goto_programt::add_instruction使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类goto_programt
的用法示例。
在下文中一共展示了goto_programt::add_instruction方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: convert_java_try_catch
void goto_convertt::convert_java_try_catch(
const codet &code,
goto_programt &dest)
{
assert(!code.operands().empty());
// add the CATCH instruction to 'dest'
goto_programt::targett catch_instruction=dest.add_instruction();
catch_instruction->make_catch();
catch_instruction->code.set_statement(ID_catch);
catch_instruction->source_location=code.source_location();
catch_instruction->function=code.source_location().get_function();
// the CATCH instruction is annotated with a list of exception IDs
const irept exceptions=code.op0().find(ID_exception_list);
if(exceptions.is_not_nil())
{
irept::subt exceptions_sub=exceptions.get_sub();
irept::subt &exception_list=
catch_instruction->code.add(ID_exception_list).get_sub();
exception_list.resize(exceptions_sub.size());
for(size_t i=0; i<exceptions_sub.size(); ++i)
exception_list[i].id(exceptions_sub[i].id());
}
// the CATCH instruction is also annotated with a list of handle labels
const irept handlers=code.op0().find(ID_label);
if(handlers.is_not_nil())
{
irept::subt handlers_sub=handlers.get_sub();
irept::subt &handlers_list=
catch_instruction->code.add(ID_label).get_sub();
handlers_list.resize(handlers_sub.size());
for(size_t i=0; i<handlers_sub.size(); ++i)
handlers_list[i].id(handlers_sub[i].id());
}
// the CATCH instruction may also signal a handler
if(code.op0().has_operands())
{
catch_instruction->code.get_sub().resize(1);
catch_instruction->code.get_sub()[0]=code.op0().op0();
}
// add a SKIP target for the end of everything
goto_programt end;
goto_programt::targett end_target=end.add_instruction();
end_target->make_skip();
end_target->source_location=code.source_location();
end_target->function=code.source_location().get_function();
// add the end-target
dest.destructive_append(end);
}
示例2: do_java_new
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;
}
示例3: add_guarded_claim
void goto_checkt::add_guarded_claim(
const exprt &_expr,
const std::string &comment,
const std::string &property_class,
const source_locationt &source_location,
const exprt &src_expr,
const guardt &guard)
{
exprt expr(_expr);
// first try simplifier on it
if(enable_simplify)
simplify(expr, ns);
// throw away trivial properties?
if(!retain_trivial && expr.is_true())
return;
// add the guard
exprt guard_expr=guard.as_expr();
exprt new_expr;
if(guard_expr.is_true())
new_expr.swap(expr);
else
{
new_expr=exprt(ID_implies, bool_typet());
new_expr.move_to_operands(guard_expr, expr);
}
if(assertions.insert(new_expr).second)
{
goto_program_instruction_typet type=
enable_assert_to_assume?ASSUME:ASSERT;
goto_programt::targett t=new_code.add_instruction(type);
std::string source_expr_string=from_expr(ns, "", src_expr);
t->guard.swap(new_expr);
t->source_location=source_location;
t->source_location.set_comment(comment+" in "+source_expr_string);
t->source_location.set_property_class(property_class);
}
}
示例4: do_function_call_other
void goto_convertt::do_function_call_other(
const exprt &lhs,
const exprt &function,
const exprt::operandst &arguments,
goto_programt &dest)
{
// don't know what to do with it
goto_programt::targett t=dest.add_instruction(FUNCTION_CALL);
code_function_callt function_call;
function_call.add_source_location()=function.source_location();
function_call.lhs()=lhs;
function_call.function()=function;
function_call.arguments()=arguments;
t->source_location=function.source_location();
t->code.swap(function_call);
}
示例5: add_guarded_claim
void goto_checkt::add_guarded_claim(const exprt &_expr,
const std::string &comment, const std::string &property,
const locationt &location, const guardt &guard)
{
bool all_claims = options.get_bool_option("all-claims");
exprt expr(_expr);
// first try simplifier on it
if (!options.get_bool_option("no-simplify"))
{
expr2tc tmpexpr;
migrate_expr(expr, tmpexpr);
base_type(tmpexpr, ns);
expr = migrate_expr_back(tmpexpr);
simplify(expr);
}
if (!all_claims && expr.is_true())
return;
// add the guard
exprt guard_expr = migrate_expr_back(guard.as_expr());
exprt new_expr;
if (guard_expr.is_true())
new_expr.swap(expr);
else
{
new_expr = exprt("=>", bool_typet());
new_expr.move_to_operands(guard_expr, expr);
}
if (assertions.insert(new_expr).second)
{
goto_programt::targett t = new_code.add_instruction(ASSERT);
migrate_expr(new_expr, t->guard);
t->location = location;
t->location.comment(comment);
t->location.property(property);
}
}
示例6: build_havoc_code
void havoc_loopst::build_havoc_code(
const goto_programt::targett loop_head,
const modifiest &modifies,
goto_programt &dest)
{
for(modifiest::const_iterator
m_it=modifies.begin();
m_it!=modifies.end();
m_it++)
{
exprt lhs=*m_it;
exprt rhs=side_effect_expr_nondett(lhs.type());
goto_programt::targett t=dest.add_instruction(ASSIGN);
t->function=loop_head->function;
t->source_location=loop_head->source_location;
t->code=code_assignt(lhs, rhs);
t->code.add_source_location()=loop_head->source_location;
}
}
示例7: do_atomic_end
void goto_convertt::do_atomic_end(
const exprt &lhs,
const exprt &function,
const exprt::operandst &arguments,
goto_programt &dest)
{
if(lhs.is_not_nil())
{
err_location(lhs);
throw "atomic_end does not expect an LHS";
}
if(!arguments.empty())
{
err_location(function);
throw "atomic_end takes no arguments";
}
goto_programt::targett t=dest.add_instruction(ATOMIC_END);
t->source_location=function.source_location();
}
示例8: invalidate_buffer
void string_instrumentationt::invalidate_buffer(
goto_programt &dest,
goto_programt::const_targett target,
const exprt &buffer,
const typet &buf_type,
const mp_integer &limit)
{
irep_idt cntr_id="string_instrumentation::$counter";
if(context.symbols.find(cntr_id)==context.symbols.end())
{
symbolt new_symbol;
new_symbol.base_name="$counter";
new_symbol.pretty_name=new_symbol.base_name;
new_symbol.name=cntr_id;
new_symbol.mode="C";
new_symbol.type=uint_type();
new_symbol.is_statevar=true;
new_symbol.lvalue=true;
new_symbol.static_lifetime=true;
context.move(new_symbol);
}
const symbolt &cntr_sym=ns.lookup(cntr_id);
// create a loop that runs over the buffer
// and invalidates every element
goto_programt::targett init=dest.add_instruction(ASSIGN);
init->location=target->location;
init->code=code_assignt(symbol_expr(cntr_sym), gen_zero(cntr_sym.type));
goto_programt::targett check=dest.add_instruction();
check->location=target->location;
goto_programt::targett invalidate=dest.add_instruction(ASSIGN);
invalidate->location=target->location;
goto_programt::targett increment=dest.add_instruction(ASSIGN);
increment->location=target->location;
exprt plus("+", uint_type());
plus.copy_to_operands(symbol_expr(cntr_sym));
plus.copy_to_operands(gen_one(uint_type()));
increment->code=code_assignt(symbol_expr(cntr_sym), plus);
goto_programt::targett back=dest.add_instruction();
back->location=target->location;
back->make_goto(check);
back->guard=true_exprt();
goto_programt::targett exit=dest.add_instruction();
exit->location=target->location;
exit->make_skip();
exprt cnt_bs, bufp;
if(buf_type.id()=="pointer")
bufp = buffer;
else
{
index_exprt index;
index.array()=buffer;
index.index()=gen_zero(uint_type());
index.type()=buf_type.subtype();
bufp = address_of_exprt(index);
}
exprt deref("dereference", buf_type.subtype());
exprt b_plus_i("+", bufp.type());
b_plus_i.copy_to_operands(bufp);
b_plus_i.copy_to_operands(symbol_expr(cntr_sym));
deref.copy_to_operands(b_plus_i);
check->make_goto(exit);
if(limit==0)
check->guard=
binary_relation_exprt(symbol_expr(cntr_sym), ">=",
buffer_size(bufp));
else
check->guard=
binary_relation_exprt(symbol_expr(cntr_sym), ">",
from_integer(limit, uint_type()));
exprt nondet=side_effect_expr_nondett(buf_type.subtype());
invalidate->code=code_assignt(deref, nondet);
}
示例9: do_function_call_symbol
void goto_convertt::do_function_call_symbol(
const exprt &lhs,
const symbol_exprt &function,
const exprt::operandst &arguments,
goto_programt &dest)
{
if(function.get_bool("#invalid_object"))
return; // ignore
// lookup symbol
const irep_idt &identifier=function.get_identifier();
const symbolt *symbol;
if(ns.lookup(identifier, symbol))
{
err_location(function);
throw "error: function `"+id2string(identifier)+"' not found";
}
if(symbol->type.id()!=ID_code)
{
err_location(function);
throw "error: function `"+id2string(identifier)+"' type mismatch: expected code";
}
if(identifier==CPROVER_PREFIX "assume" ||
identifier=="__VERIFIER_assume")
{
if(arguments.size()!=1)
{
err_location(function);
throw "`"+id2string(identifier)+"' expected to have one argument";
}
goto_programt::targett t=dest.add_instruction(ASSUME);
t->guard=arguments.front();
t->source_location=function.source_location();
t->source_location.set("user-provided", true);
// let's double-check the type of the argument
if(t->guard.type().id()!=ID_bool)
t->guard.make_typecast(bool_typet());
if(lhs.is_not_nil())
{
err_location(function);
throw id2string(identifier)+" expected not to have LHS";
}
}
else if(identifier=="__VERIFIER_error")
{
if(!arguments.empty())
{
err_location(function);
throw "`"+id2string(identifier)+"' expected to have no arguments";
}
goto_programt::targett t=dest.add_instruction(ASSERT);
t->guard=false_exprt();
t->source_location=function.source_location();
t->source_location.set("user-provided", true);
t->source_location.set_property_class(ID_assertion);
if(lhs.is_not_nil())
{
err_location(function);
throw id2string(identifier)+" expected not to have LHS";
}
}
else if(has_prefix(id2string(identifier), "java::java.lang.AssertionError.<init>:"))
{
// insert function call anyway
code_function_callt function_call;
function_call.lhs()=lhs;
function_call.function()=function;
function_call.arguments()=arguments;
function_call.add_source_location()=function.source_location();
copy(function_call, FUNCTION_CALL, dest);
if(arguments.size()!=1 && arguments.size()!=2)
{
err_location(function);
throw "`"+id2string(identifier)+"' expected to have one or two arguments";
}
goto_programt::targett t=dest.add_instruction(ASSERT);
t->guard=false_exprt();
t->source_location=function.source_location();
t->source_location.set("user-provided", true);
t->source_location.set_property_class(ID_assertion);
t->source_location.set_comment("assertion at "+function.source_location().as_string());
}
else if(identifier=="assert" &&
!ns.lookup(identifier).location.get_function().empty())
{
if(arguments.size()!=1)
{
err_location(function);
throw "`"+id2string(identifier)+"' expected to have one argument";
//.........这里部分代码省略.........
示例10: parameter_assignments
void goto_inlinet::parameter_assignments(
const locationt &location,
const code_typet &code_type,
const exprt::operandst &arguments,
goto_programt &dest)
{
// iterates over the operands
exprt::operandst::const_iterator it1=arguments.begin();
goto_programt::local_variablest local_variables;
const code_typet::argumentst &argument_types=
code_type.arguments();
// iterates over the types of the arguments
for(code_typet::argumentst::const_iterator
it2=argument_types.begin();
it2!=argument_types.end();
it2++)
{
// if you run out of actual arguments there was a mismatch
if(it1==arguments.end())
{
err_location(location);
throw "function call: not enough arguments";
}
const exprt &argument=static_cast<const exprt &>(*it2);
// this is the type the n-th argument should be
const typet &arg_type=ns.follow(argument.type());
const irep_idt &identifier=argument.cmt_identifier();
if(identifier=="")
{
err_location(location);
throw "no identifier for function argument";
}
{
const symbolt &symbol=ns.lookup(identifier);
goto_programt::targett decl=dest.add_instruction();
decl->make_other();
exprt tmp = code_declt(symbol_expr(symbol));
migrate_expr(tmp, decl->code);
decl->location=location;
decl->function=location.get_function();
decl->local_variables=local_variables;
}
local_variables.insert(identifier);
// nil means "don't assign"
if(it1->is_nil())
{
}
else
{
// this is the actual parameter
exprt actual(*it1);
// it should be the same exact type
type2tc arg_type_2, actual_type_2;
migrate_type(arg_type, arg_type_2);
migrate_type(actual.type(), actual_type_2);
if (!base_type_eq(arg_type_2, actual_type_2, ns))
{
const typet &f_argtype = ns.follow(arg_type);
const typet &f_acttype = ns.follow(actual.type());
// we are willing to do some conversion
if((f_argtype.id()=="pointer" &&
f_acttype.id()=="pointer") ||
(f_argtype.is_array() &&
f_acttype.id()=="pointer" &&
f_argtype.subtype()==f_acttype.subtype()))
{
actual.make_typecast(arg_type);
}
else if((f_argtype.id()=="signedbv" ||
f_argtype.id()=="unsignedbv" ||
f_argtype.is_bool()) &&
(f_acttype.id()=="signedbv" ||
f_acttype.id()=="unsignedbv" ||
f_acttype.is_bool()))
{
actual.make_typecast(arg_type);
}
else
{
err_location(location);
str << "function call: argument `" << identifier
<< "' type mismatch: got "
<< from_type(ns, identifier, it1->type())
<< ", expected "
<< from_type(ns, identifier, arg_type);
throw 0;
//.........这里部分代码省略.........
示例11: goto_check
void goto_checkt::goto_check(goto_functiont &goto_function)
{
{
const symbolt *init_symbol;
if(!ns.lookup(CPROVER_PREFIX "initialize", init_symbol))
mode=init_symbol->mode;
}
assertions.clear();
local_bitvector_analysist local_bitvector_analysis_obj(goto_function);
local_bitvector_analysis=&local_bitvector_analysis_obj;
goto_programt &goto_program=goto_function.body;
Forall_goto_program_instructions(it, goto_program)
{
t=it;
goto_programt::instructiont &i=*it;
new_code.clear();
// we clear all recorded assertions if
// 1) we want to generate all assertions or
// 2) the instruction is a branch target
if(retain_trivial ||
i.is_target())
assertions.clear();
check(i.guard);
// magic ERROR label?
for(optionst::value_listt::const_iterator
l_it=error_labels.begin();
l_it!=error_labels.end();
l_it++)
{
if(std::find(i.labels.begin(), i.labels.end(), *l_it)!=i.labels.end())
{
goto_program_instruction_typet type=
enable_assert_to_assume?ASSUME:ASSERT;
goto_programt::targett t=new_code.add_instruction(type);
t->guard=false_exprt();
t->source_location=i.source_location;
t->source_location.set_property_class("error label");
t->source_location.set_comment("error label "+*l_it);
t->source_location.set("user-provided", true);
}
}
if(i.is_other())
{
const irep_idt &statement=i.code.get(ID_statement);
if(statement==ID_expression)
{
check(i.code);
}
else if(statement==ID_printf)
{
forall_operands(it, i.code)
check(*it);
}
}
else if(i.is_assign())
{
const code_assignt &code_assign=to_code_assign(i.code);
check(code_assign.lhs());
check(code_assign.rhs());
// the LHS might invalidate any assertion
invalidate(code_assign.lhs());
}
else if(i.is_function_call())
{
const code_function_callt &code_function_call=
to_code_function_call(i.code);
// for Java, need to check whether 'this' is null
// on non-static method invocations
if(mode==ID_java &&
enable_pointer_check &&
!code_function_call.arguments().empty() &&
code_function_call.function().type().id()==ID_code &&
to_code_type(code_function_call.function().type()).has_this())
{
exprt pointer=code_function_call.arguments()[0];
local_bitvector_analysist::flagst flags=
local_bitvector_analysis->get(t, pointer);
if(flags.is_unknown() || flags.is_null())
{
notequal_exprt not_eq_null(pointer, gen_zero(pointer.type()));
add_guarded_claim(
not_eq_null,
//.........这里部分代码省略.........
示例12: replace_return
void goto_inlinet::replace_return(
goto_programt &dest,
const exprt &lhs,
const exprt &constrain __attribute__((unused)) /* ndebug */)
{
for(goto_programt::instructionst::iterator
it=dest.instructions.begin();
it!=dest.instructions.end();
it++)
{
if(it->is_return())
{
if(lhs.is_not_nil())
{
goto_programt tmp;
goto_programt::targett assignment=tmp.add_instruction(ASSIGN);
const code_return2t &ret = to_code_return2t(it->code);
code_assignt code_assign(lhs, migrate_expr_back(ret.operand));
// this may happen if the declared return type at the call site
// differs from the defined return type
if(code_assign.lhs().type()!=
code_assign.rhs().type())
code_assign.rhs().make_typecast(code_assign.lhs().type());
migrate_expr(code_assign, assignment->code);
assignment->location=it->location;
assignment->local_variables=it->local_variables;
assignment->function=it->location.get_function();
示例13: do_cpp_new
void goto_convertt::do_cpp_new(
const exprt &lhs,
const side_effect_exprt &rhs,
goto_programt &dest)
{
if(lhs.is_nil())
throw "do_cpp_new without lhs is yet to be implemented";
// build size expression
exprt object_size=
static_cast<const exprt &>(rhs.find(ID_sizeof));
bool new_array=rhs.get(ID_statement)==ID_cpp_new_array;
exprt count;
if(new_array)
{
count=static_cast<const exprt &>(rhs.find(ID_size));
if(count.type()!=object_size.type())
count.make_typecast(object_size.type());
// might have side-effect
clean_expr(count, dest);
}
exprt tmp_symbol_expr;
// is this a placement new?
if(rhs.operands().empty()) // no, "regular" one
{
// call __new or __new_array
exprt new_symbol=
ns.lookup(new_array?"__new_array":"__new").symbol_expr();
const code_typet &code_type=
to_code_type(new_symbol.type());
const typet &return_type=
code_type.return_type();
assert(code_type.parameters().size()==1 ||
code_type.parameters().size()==2);
const symbolt &tmp_symbol=
new_tmp_symbol(return_type, "new", dest, rhs.source_location());
tmp_symbol_expr=tmp_symbol.symbol_expr();
code_function_callt new_call;
new_call.function()=new_symbol;
if(new_array) new_call.arguments().push_back(count);
new_call.arguments().push_back(object_size);
new_call.set("#type", lhs.type().subtype());
new_call.lhs()=tmp_symbol_expr;
new_call.add_source_location()=rhs.source_location();
convert(new_call, dest);
}
else if(rhs.operands().size()==1)
{
// call __placement_new
exprt new_symbol=
ns.lookup(new_array?"__placement_new_array":"__placement_new").symbol_expr();
const code_typet &code_type=
to_code_type(new_symbol.type());
const typet &return_type=code_type.return_type();
assert(code_type.parameters().size()==2 ||
code_type.parameters().size()==3);
const symbolt &tmp_symbol=
new_tmp_symbol(return_type, "new", dest, rhs.source_location());
tmp_symbol_expr=tmp_symbol.symbol_expr();
code_function_callt new_call;
new_call.function()=new_symbol;
if(new_array) new_call.arguments().push_back(count);
new_call.arguments().push_back(object_size);
new_call.arguments().push_back(rhs.op0()); // memory location
new_call.set("#type", lhs.type().subtype());
new_call.lhs()=tmp_symbol_expr;
new_call.add_source_location()=rhs.source_location();
for(unsigned i=0; i<code_type.parameters().size(); i++)
if(new_call.arguments()[i].type()!=code_type.parameters()[i].type())
new_call.arguments()[i].make_typecast(code_type.parameters()[i].type());
convert(new_call, dest);
}
else
throw "cpp_new expected to have 0 or 1 operands";
goto_programt::targett t_n=dest.add_instruction(ASSIGN);
t_n->code=code_assignt(
lhs, typecast_exprt(tmp_symbol_expr, lhs.type()));
//.........这里部分代码省略.........
示例14: do_format_string_write
void string_instrumentationt::do_format_string_write(
goto_programt &dest,
goto_programt::const_targett target,
const code_function_callt::argumentst &arguments,
unsigned format_string_inx,
unsigned argument_start_inx,
const std::string &function_name)
{
const exprt &format_arg = arguments[format_string_inx];
if(format_arg.id()=="address_of" &&
format_arg.op0().id()=="index" &&
format_arg.op0().op0().id()==ID_string_constant) // constant format
{
format_token_listt token_list;
parse_format_string(format_arg.op0().op0(), token_list);
unsigned args=0;
for(format_token_listt::const_iterator it=token_list.begin();
it!=token_list.end();
it++)
{
if(find(it->flags.begin(), it->flags.end(), format_tokent::ASTERISK)!=
it->flags.end())
continue; // asterisk means `ignore this'
switch(it->type)
{
case format_tokent::STRING:
{
const exprt &argument=arguments[argument_start_inx+args];
const typet &arg_type=ns.follow(argument.type());
goto_programt::targett assertion=dest.add_instruction();
assertion->location=target->location;
assertion->location.set("property", "string");
std::string comment("format string buffer overflow in ");
comment += function_name;
assertion->location.set("comment", comment);
if(it->field_width!=0)
{
exprt fwidth = from_integer(it->field_width, uint_type());
exprt fw_1("+", uint_type());
exprt one = gen_one(uint_type());
fw_1.move_to_operands(fwidth);
fw_1.move_to_operands(one); // +1 for 0-char
exprt fw_lt_bs;
if(arg_type.id()=="pointer")
fw_lt_bs=binary_relation_exprt(fw_1, "<=", buffer_size(argument));
else
{
index_exprt index;
index.array()=argument;
index.index()=gen_zero(uint_type());
address_of_exprt aof(index);
fw_lt_bs=binary_relation_exprt(fw_1, "<=", buffer_size(aof));
}
assertion->make_assertion(fw_lt_bs);
}
else
{
// this is a possible overflow.
assertion->make_assertion(false_exprt());
}
// now kill the contents
invalidate_buffer(dest, target, argument, arg_type, it->field_width);
args++;
break;
}
case format_tokent::TEXT:
case format_tokent::UNKNOWN:
{
// nothing
break;
}
default: // everything else
{
const exprt &argument=arguments[argument_start_inx+args];
const typet &arg_type=ns.follow(argument.type());
goto_programt::targett assignment=dest.add_instruction(ASSIGN);
assignment->location=target->location;
exprt lhs("dereference", arg_type.subtype());
lhs.copy_to_operands(argument);
exprt rhs=side_effect_expr_nondett(lhs.type());
rhs.location()=target->location;
assignment->code=code_assignt(lhs, rhs);
args++;
//.........这里部分代码省略.........
示例15: do_format_string_read
void string_instrumentationt::do_format_string_read(
goto_programt &dest,
goto_programt::const_targett target,
const code_function_callt::argumentst &arguments,
unsigned format_string_inx,
unsigned argument_start_inx,
const std::string &function_name)
{
const exprt &format_arg = arguments[format_string_inx];
if(format_arg.id()=="address_of" &&
format_arg.op0().id()=="index" &&
format_arg.op0().op0().id()==ID_string_constant)
{
format_token_listt token_list;
parse_format_string(format_arg.op0().op0(), token_list);
unsigned args=0;
for(format_token_listt::const_iterator it=token_list.begin();
it!=token_list.end();
it++)
{
if(it->type==format_tokent::STRING)
{
const exprt &arg = arguments[argument_start_inx+args];
const typet &arg_type = ns.follow(arg.type());
if(arg.id()!=ID_string_constant) // we don't need to check constants
{
goto_programt::targett assertion=dest.add_instruction();
assertion->location=target->location;
assertion->location.set("property", "string");
std::string comment("zero-termination of string argument of ");
comment += function_name;
assertion->location.set("comment", comment);
exprt temp(arg);
if(arg_type.id()!="pointer")
{
index_exprt index;
index.array()=temp;
index.index()=gen_zero(uint_type());
index.type()=arg_type.subtype();
temp=address_of_exprt(index);
}
assertion->make_assertion(is_zero_string(temp));
}
}
if(it->type!=format_tokent::TEXT &&
it->type!=format_tokent::UNKNOWN) args++;
if(find(it->flags.begin(), it->flags.end(), format_tokent::ASTERISK)!=
it->flags.end())
args++; // just eat the additional argument
}
}
else // non-const format string
{
goto_programt::targett format_ass=dest.add_instruction();
format_ass->make_assertion(is_zero_string(arguments[1]));
format_ass->location=target->location;
format_ass->location.set("property", "string");
std::string comment("zero-termination of format string of ");
comment += function_name;
format_ass->location.set("comment", comment);
for(unsigned i=2; i<arguments.size(); i++)
{
const exprt &arg = arguments[i];
const typet &arg_type=ns.follow(arguments[i].type());
if(arguments[i].id()!=ID_string_constant &&
is_string_type(arg_type))
{
goto_programt::targett assertion=dest.add_instruction();
assertion->location=target->location;
assertion->location.set("property", "string");
std::string comment("zero-termination of string argument of ");
comment += function_name;
assertion->location.set("comment", comment);
exprt temp(arg);
if(arg_type.id()!="pointer")
{
index_exprt index;
index.array()=temp;
index.index()=gen_zero(uint_type());
index.type()=arg_type.subtype();
temp=address_of_exprt(index);
}
assertion->make_assertion(is_zero_string(temp));
}
}
}
//.........这里部分代码省略.........