@@ -31,10 +31,15 @@ Date: April 2016
31
31
Function: model_argc_argv
32
32
33
33
Inputs:
34
+ symbol_table: Input program's symbol table
35
+ goto_functions: Input program's intermediate representation
36
+ max_argc: User-specified maximum number of arguments to be modelled
37
+ message_handler: message logging
34
38
35
- Outputs:
39
+ Outputs: True, if and only if modelling succeeded
36
40
37
- Purpose:
41
+ Purpose: Set up argv with up to max_argc pointers into an array of
42
+ 4096 bytes
38
43
39
44
\*******************************************************************/
40
45
@@ -47,37 +52,23 @@ bool model_argc_argv(
47
52
messaget message (message_handler);
48
53
const namespacet ns (symbol_table);
49
54
50
- const symbolt *init_symbol=0 ;
51
- if (ns.lookup (CPROVER_PREFIX " initialize" , init_symbol))
55
+ if (!symbol_table.has_symbol (goto_functions.entry_point ()))
52
56
{
53
57
message.error () << " Linking not done, missing "
54
- << CPROVER_PREFIX " initialize " << messaget::eom;
58
+ << goto_functions. entry_point () << messaget::eom;
55
59
return true ;
56
60
}
57
61
58
- if (init_symbol->mode !=ID_C)
62
+ const symbolt &main_symbol=
63
+ ns.lookup (config.main .empty ()?ID_main:config.main );
64
+
65
+ if (main_symbol.mode !=ID_C)
59
66
{
60
67
message.error () << " argc/argv modelling is C specific"
61
68
<< messaget::eom;
62
69
return true ;
63
70
}
64
71
65
- goto_functionst::function_mapt::iterator init_entry=
66
- goto_functions.function_map .find (CPROVER_PREFIX " initialize" );
67
- assert (
68
- init_entry!=goto_functions.function_map .end () &&
69
- init_entry->second .body_available ());
70
-
71
- goto_programt &init=init_entry->second .body ;
72
- goto_programt::targett init_end=init.instructions .end ();
73
- --init_end;
74
- assert (init_end->is_end_function ());
75
- assert (init_end!=init.instructions .begin ());
76
- --init_end;
77
-
78
- const symbolt &main_symbol=
79
- ns.lookup (config.main .empty ()?ID_main:config.main );
80
-
81
72
const code_typet::parameterst ¶meters=
82
73
to_code_type (main_symbol.type ).parameters ();
83
74
if (parameters.size ()!=2 &&
@@ -95,13 +86,14 @@ bool model_argc_argv(
95
86
std::ostringstream oss;
96
87
oss << " int ARGC;\n "
97
88
<< " char *ARGV[1];\n "
98
- << " void " CPROVER_PREFIX " initialize ()\n "
89
+ << " void " << goto_functions. entry_point () << " ()\n "
99
90
<< " {\n "
100
91
<< " unsigned next=0u;\n "
101
92
<< " " CPROVER_PREFIX " assume(ARGC>=1);\n "
102
93
<< " " CPROVER_PREFIX " assume(ARGC<=" << max_argc << " );\n "
103
- << " " CPROVER_PREFIX " thread_local static char arg_string[4096];\n "
104
- << " for(unsigned i=0u; i<ARGC && i<" << max_argc << " ; ++i)\n "
94
+ << " char arg_string[4096];\n "
95
+ << " __CPROVER_input(\" arg_string\" , &arg_string[0]);\n "
96
+ << " for(int i=0; i<ARGC && i<" << max_argc << " ; ++i)\n "
105
97
<< " {\n "
106
98
<< " unsigned len;\n "
107
99
<< " " CPROVER_PREFIX " assume(len<4096);\n "
@@ -123,17 +115,18 @@ bool model_argc_argv(
123
115
symbol_tablet tmp_symbol_table;
124
116
ansi_c_language.typecheck (tmp_symbol_table, " <built-in-library>" );
125
117
126
- goto_programt tmp ;
118
+ goto_programt init_instructions ;
127
119
exprt value=nil_exprt ();
128
- // locate the body of the newly built initialize function as well
129
- // as any additional declarations we might need; the body will then
130
- // be converted and appended to the existing initialize function
120
+ // locate the body of the newly built start function as well as any
121
+ // additional declarations we might need; the body will then be
122
+ // converted and inserted into the start function
131
123
forall_symbols (it, tmp_symbol_table.symbols )
132
124
{
133
125
// add __CPROVER_assume if necessary (it might exist already)
134
- if (it->first ==CPROVER_PREFIX " assume" )
126
+ if (it->first ==CPROVER_PREFIX " assume" ||
127
+ it->first ==CPROVER_PREFIX " input" )
135
128
symbol_table.add (it->second );
136
- else if (it->first ==CPROVER_PREFIX " initialize " )
129
+ else if (it->first ==goto_functions. entry_point () )
137
130
{
138
131
value=it->second .value ;
139
132
@@ -143,7 +136,7 @@ bool model_argc_argv(
143
136
replace (value);
144
137
}
145
138
else if (has_prefix (id2string (it->first ),
146
- CPROVER_PREFIX " initialize ::" ) &&
139
+ id2string (goto_functions. entry_point ())+ " ::" ) &&
147
140
symbol_table.add (it->second ))
148
141
assert (false );
149
142
}
@@ -152,20 +145,41 @@ bool model_argc_argv(
152
145
goto_convert (
153
146
to_code (value),
154
147
symbol_table,
155
- tmp ,
148
+ init_instructions ,
156
149
message_handler);
157
- Forall_goto_program_instructions (it, tmp )
150
+ Forall_goto_program_instructions (it, init_instructions )
158
151
{
159
152
it->source_location .set_file (" <built-in-library>" );
160
- it->function =CPROVER_PREFIX " initialize " ;
153
+ it->function =goto_functions. entry_point () ;
161
154
}
162
- init.insert_before_swap (init_end, tmp);
155
+
156
+ goto_functionst::function_mapt::iterator start_entry=
157
+ goto_functions.function_map .find (goto_functions.entry_point ());
158
+ assert (
159
+ start_entry!=goto_functions.function_map .end () &&
160
+ start_entry->second .body_available ());
161
+
162
+ goto_programt &start=start_entry->second .body ;
163
+ goto_programt::targett main_call=start.instructions .begin ();
164
+ for (goto_programt::targett end=start.instructions .end ();
165
+ main_call!=end;
166
+ ++main_call)
167
+ if (main_call->is_function_call ())
168
+ {
169
+ const exprt &func=
170
+ to_code_function_call (main_call->code ).function ();
171
+ if (func.id ()==ID_symbol &&
172
+ to_symbol_expr (func).get_identifier ()==main_symbol.name )
173
+ break ;
174
+ }
175
+
176
+ assert (main_call!=start.instructions .end ());
177
+ start.insert_before_swap (main_call, init_instructions);
163
178
164
179
// update counters etc.
165
- remove_skip (init );
166
- init .compute_loop_numbers ();
180
+ remove_skip (start );
181
+ start .compute_loop_numbers ();
167
182
goto_functions.update ();
168
183
169
184
return false ;
170
185
}
171
-
0 commit comments