Skip to content

Commit 4c94e7c

Browse files
committed
goto-instrument model-argc-argv: place environment in __CPROVER__start
argc/argv modelling was previously placed in __CPROVER_initialize. To align with Java environment modelling, this is now moved to __CPROVER__start, just before the call to main().
1 parent 15a67e4 commit 4c94e7c

File tree

1 file changed

+52
-37
lines changed

1 file changed

+52
-37
lines changed

src/goto-instrument/model_argc_argv.cpp

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ Date: April 2016
2929
#include <goto-programs/goto_functions.h>
3030
#include <goto-programs/remove_skip.h>
3131

32+
/// Set up argv with up to max_argc pointers into an array of 4096 bytes.
33+
/// \param symbol_table: Input program's symbol table
34+
/// \param goto_functions: Input program's intermediate representation
35+
/// \param max_argc: User-specified maximum number of arguments to be modelled
36+
/// \param message_handler: message logging
37+
/// \return True, if and only if modelling succeeded
3238
bool model_argc_argv(
3339
symbol_tablet &symbol_table,
3440
goto_functionst &goto_functions,
@@ -38,37 +44,23 @@ bool model_argc_argv(
3844
messaget message(message_handler);
3945
const namespacet ns(symbol_table);
4046

41-
const symbolt *init_symbol=nullptr;
42-
if(ns.lookup(CPROVER_PREFIX "initialize", init_symbol))
47+
if(!symbol_table.has_symbol(goto_functions.entry_point()))
4348
{
4449
message.error() << "Linking not done, missing "
45-
<< CPROVER_PREFIX "initialize" << messaget::eom;
50+
<< goto_functions.entry_point() << messaget::eom;
4651
return true;
4752
}
4853

49-
if(init_symbol->mode!=ID_C)
54+
const symbolt &main_symbol=
55+
ns.lookup(config.main.empty()?ID_main:config.main);
56+
57+
if(main_symbol.mode!=ID_C)
5058
{
5159
message.error() << "argc/argv modelling is C specific"
5260
<< messaget::eom;
5361
return true;
5462
}
5563

56-
goto_functionst::function_mapt::iterator init_entry=
57-
goto_functions.function_map.find(CPROVER_PREFIX "initialize");
58-
assert(
59-
init_entry!=goto_functions.function_map.end() &&
60-
init_entry->second.body_available());
61-
62-
goto_programt &init=init_entry->second.body;
63-
goto_programt::targett init_end=init.instructions.end();
64-
--init_end;
65-
assert(init_end->is_end_function());
66-
assert(init_end!=init.instructions.begin());
67-
--init_end;
68-
69-
const symbolt &main_symbol=
70-
ns.lookup(config.main.empty()?ID_main:config.main);
71-
7264
const code_typet::parameterst &parameters=
7365
to_code_type(main_symbol.type).parameters();
7466
if(parameters.size()!=2 &&
@@ -86,13 +78,14 @@ bool model_argc_argv(
8678
std::ostringstream oss;
8779
oss << "int ARGC;\n"
8880
<< "char *ARGV[1];\n"
89-
<< "void " CPROVER_PREFIX "initialize()\n"
81+
<< "void " << goto_functions.entry_point() << "()\n"
9082
<< "{\n"
9183
<< " unsigned next=0u;\n"
9284
<< " " CPROVER_PREFIX "assume(ARGC>=1);\n"
9385
<< " " CPROVER_PREFIX "assume(ARGC<=" << max_argc << ");\n"
94-
<< " " CPROVER_PREFIX "thread_local static char arg_string[4096];\n"
95-
<< " for(unsigned i=0u; i<ARGC && i<" << max_argc << "; ++i)\n"
86+
<< " char arg_string[4096];\n"
87+
<< " __CPROVER_input(\"arg_string\", &arg_string[0]);\n"
88+
<< " for(int i=0; i<ARGC && i<" << max_argc << "; ++i)\n"
9689
<< " {\n"
9790
<< " unsigned len;\n"
9891
<< " " CPROVER_PREFIX "assume(len<4096);\n"
@@ -114,17 +107,18 @@ bool model_argc_argv(
114107
symbol_tablet tmp_symbol_table;
115108
ansi_c_language.typecheck(tmp_symbol_table, "<built-in-library>");
116109

117-
goto_programt tmp;
110+
goto_programt init_instructions;
118111
exprt value=nil_exprt();
119-
// locate the body of the newly built initialize function as well
120-
// as any additional declarations we might need; the body will then
121-
// be converted and appended to the existing initialize function
112+
// locate the body of the newly built start function as well as any
113+
// additional declarations we might need; the body will then be
114+
// converted and inserted into the start function
122115
forall_symbols(it, tmp_symbol_table.symbols)
123116
{
124117
// add __CPROVER_assume if necessary (it might exist already)
125-
if(it->first==CPROVER_PREFIX "assume")
118+
if(it->first==CPROVER_PREFIX "assume" ||
119+
it->first==CPROVER_PREFIX "input")
126120
symbol_table.add(it->second);
127-
else if(it->first==CPROVER_PREFIX "initialize")
121+
else if(it->first==goto_functions.entry_point())
128122
{
129123
value=it->second.value;
130124

@@ -134,7 +128,7 @@ bool model_argc_argv(
134128
replace(value);
135129
}
136130
else if(has_prefix(id2string(it->first),
137-
CPROVER_PREFIX "initialize::") &&
131+
id2string(goto_functions.entry_point())+"::") &&
138132
symbol_table.add(it->second))
139133
UNREACHABLE;
140134
}
@@ -143,20 +137,41 @@ bool model_argc_argv(
143137
goto_convert(
144138
to_code(value),
145139
symbol_table,
146-
tmp,
140+
init_instructions,
147141
message_handler);
148-
Forall_goto_program_instructions(it, tmp)
142+
Forall_goto_program_instructions(it, init_instructions)
149143
{
150144
it->source_location.set_file("<built-in-library>");
151-
it->function=CPROVER_PREFIX "initialize";
145+
it->function=goto_functions.entry_point();
152146
}
153-
init.insert_before_swap(init_end, tmp);
147+
148+
goto_functionst::function_mapt::iterator start_entry=
149+
goto_functions.function_map.find(goto_functions.entry_point());
150+
assert(
151+
start_entry!=goto_functions.function_map.end() &&
152+
start_entry->second.body_available());
153+
154+
goto_programt &start=start_entry->second.body;
155+
goto_programt::targett main_call=start.instructions.begin();
156+
for(goto_programt::targett end=start.instructions.end();
157+
main_call!=end;
158+
++main_call)
159+
if(main_call->is_function_call())
160+
{
161+
const exprt &func=
162+
to_code_function_call(main_call->code).function();
163+
if(func.id()==ID_symbol &&
164+
to_symbol_expr(func).get_identifier()==main_symbol.name)
165+
break;
166+
}
167+
168+
assert(main_call!=start.instructions.end());
169+
start.insert_before_swap(main_call, init_instructions);
154170

155171
// update counters etc.
156-
remove_skip(init);
157-
init.compute_loop_numbers();
172+
remove_skip(start);
173+
start.compute_loop_numbers();
158174
goto_functions.update();
159175

160176
return false;
161177
}
162-

0 commit comments

Comments
 (0)