@@ -260,6 +260,9 @@ bool ai_baset::visit(
260260 }
261261 else
262262 {
263+ // initialize state, if necessary
264+ get_state (to_l);
265+
263266 new_values.transform (l, to_l, *this , ns);
264267
265268 if (merge (new_values, l, to_l))
@@ -295,25 +298,48 @@ bool ai_baset::do_function_call(
295298 const exprt::operandst &arguments,
296299 const namespacet &ns)
297300{
301+ // initialize state, if necessary
302+ get_state (l_return);
303+
298304 const goto_functionst::goto_functiont &goto_function=
299305 f_it->second ;
300306
301307 if (!goto_function.body_available )
302- return false ; // do nothing, no change
308+ {
309+ std::unique_ptr<statet> tmp_state (make_temporary_state (get_state (l_call)));
310+ tmp_state->transform (l_call, l_return, *this , ns);
311+
312+ return merge (*tmp_state, l_call, l_return);
313+ }
303314
304315 assert (!goto_function.body .instructions .empty ());
305316
306317 {
307318 // get the state at the beginning of the function
308319 locationt l_begin=goto_function.body .instructions .begin ();
320+ // initialize state, if necessary
321+ get_state (l_begin);
309322
310323 // do the edge from the call site to the beginning of the function
311- std::unique_ptr<statet> state (make_temporary_state (get_state (l_call)));
324+ std::unique_ptr<statet> tmp_state (make_temporary_state (get_state (l_call)));
325+ tmp_state->transform (l_call, l_begin, *this , ns);
326+
327+ bool new_data=false ;
312328
313- state->transform (l_call, l_begin, *this , ns);
314-
315329 // merge the new stuff
316- if (merge (*state, l_call, l_begin))
330+ if (merge (*tmp_state, l_call, l_begin))
331+ new_data=true ;
332+
333+ // do each function at least once
334+ if (functions_done.find (f_it->first )==
335+ functions_done.end ())
336+ {
337+ new_data=true ;
338+ functions_done.insert (f_it->first );
339+ }
340+
341+ // do we need to do the fixedpoint of the body?
342+ if (new_data)
317343 {
318344 // also do the fixedpoint of the body via a recursive call
319345 fixedpoint (goto_function.body , goto_functions, ns);
@@ -326,15 +352,13 @@ bool ai_baset::do_function_call(
326352 assert (l_end->is_end_function ());
327353
328354 // do edge from end of function to instruction after call
329- locationt l_next=l_call;
330- l_next++;
331-
332- std::unique_ptr<statet> state (make_temporary_state (get_state (l_end)));
333-
334- state->transform (l_end, l_next, *this , ns);
355+ std::unique_ptr<statet> tmp_state (make_temporary_state (get_state (l_end)));
356+ tmp_state->transform (l_end, l_return, *this , ns);
335357
336- // Propagate those -- not exceedingly precise, this is.
337- return merge (*state, l_end, l_next);
358+ // Propagate those -- not exceedingly precise, this is,
359+ // as still it contains all the state from the
360+ // call site
361+ return merge (*tmp_state, l_end, l_return);
338362 }
339363}
340364
0 commit comments