@@ -178,44 +178,59 @@ void goto_symext::symex_function_call(
178
178
{
179
179
const exprt &function = instruction.call_function ();
180
180
181
- // If at some point symex_function_call can support more
182
- // expression ids(), like ID_Dereference, please expand the
183
- // precondition appropriately.
184
- PRECONDITION (function.id () == ID_symbol);
185
-
186
- symex_function_call_symbol (
187
- get_goto_function,
188
- state,
189
- instruction.call_lhs (),
190
- to_symbol_expr (instruction.call_function ()),
191
- instruction.call_arguments ());
192
- }
181
+ PRECONDITION (function.id () == ID_symbol || function.id () == ID_dereference);
193
182
194
- void goto_symext::symex_function_call_symbol (
195
- const get_goto_functiont &get_goto_function,
196
- statet &state,
197
- const exprt &lhs,
198
- const symbol_exprt &function,
199
- const exprt::operandst &arguments)
200
- {
183
+ // clean lhs
201
184
exprt cleaned_lhs;
202
185
203
- if (lhs .is_nil ())
204
- cleaned_lhs = lhs ;
186
+ if (instruction. call_lhs () .is_nil ())
187
+ cleaned_lhs = nil_exprt () ;
205
188
else
206
- cleaned_lhs = clean_expr (lhs , state, true );
189
+ cleaned_lhs = clean_expr (instruction. call_lhs () , state, true );
207
190
208
- // no need to clean the function, which is a symbol only
191
+ // need to clean the function expression in case it's a dereference
192
+ auto cleaned_function = clean_expr (function, state, false );
209
193
194
+ // clean the arguments
210
195
exprt::operandst cleaned_arguments;
211
196
212
- for (auto &argument : arguments )
197
+ for (auto &argument : instruction. call_arguments () )
213
198
cleaned_arguments.push_back (clean_expr (argument, state, false ));
214
199
215
200
target.location (state.guard .as_expr (), state.source );
216
201
217
- symex_function_call_post_clean (
218
- get_goto_function, state, cleaned_lhs, function, cleaned_arguments);
202
+ // We get an if-then-else nest that contains symbols
203
+ // in the case of function pointers, and we traverse that recursively.
204
+ symex_function_call_post_clean_rec (
205
+ get_goto_function, state, cleaned_lhs, cleaned_function, cleaned_arguments);
206
+ }
207
+
208
+ void goto_symext::symex_function_call_post_clean_rec (
209
+ const get_goto_functiont &get_goto_function,
210
+ statet &state,
211
+ const exprt &cleaned_lhs,
212
+ const exprt &cleaned_function,
213
+ const exprt::operandst &cleaned_arguments)
214
+ {
215
+ if (cleaned_function.id () == ID_symbol)
216
+ {
217
+ symex_function_call_post_clean (
218
+ get_goto_function,
219
+ state,
220
+ cleaned_lhs,
221
+ to_symbol_expr (cleaned_function),
222
+ cleaned_arguments);
223
+ }
224
+ else if (cleaned_function.id () == ID_if)
225
+ {
226
+ DATA_INVARIANT_WITH_DIAGNOSTICS (
227
+ false , " todo" , irep_pretty_diagnosticst (cleaned_function));
228
+ }
229
+ else
230
+ DATA_INVARIANT_WITH_DIAGNOSTICS (
231
+ false ,
232
+ " cleaned function is expected to consist of if and symbol" ,
233
+ irep_pretty_diagnosticst (cleaned_function));
219
234
}
220
235
221
236
void goto_symext::symex_function_call_post_clean (
0 commit comments