@@ -20,6 +20,30 @@ Author: Daniel Kroening, kroening@kroening.com
2020
2121#include " goto_symex.h"
2222
23+ void goto_symext::symex_transition (
24+ statet &state,
25+ goto_programt::const_targett to,
26+ bool is_backwards_goto)
27+ {
28+ if (!state.call_stack ().empty ())
29+ {
30+ // initialize the loop counter of any loop we are newly entering
31+ // upon this transition; we are entering a loop if
32+ // 1. the transition from state.source.pc to "to" is not a backwards goto
33+ // or
34+ // 2. we are arriving from an outer loop
35+ statet::framet &frame=state.top ();
36+ const goto_programt::instructiont &instruction=*to;
37+ for (const auto &i_e : instruction.incoming_edges )
38+ if (i_e->is_goto () && i_e->is_backwards_goto () &&
39+ (!is_backwards_goto ||
40+ state.source .pc ->location_number >i_e->location_number ))
41+ frame.loop_iterations [goto_programt::loop_id (i_e)].count =0 ;
42+ }
43+
44+ state.source .pc =to;
45+ }
46+
2347void goto_symext::new_name (symbolt &symbol)
2448{
2549 get_new_name (symbol, ns);
@@ -114,6 +138,8 @@ void goto_symext::operator()(
114138 state.symex_target =⌖
115139 state.dirty =new dirtyt (goto_functions);
116140
141+ symex_transition (state, state.source .pc );
142+
117143 assert (state.top ().end_of_function ->is_end_function ());
118144
119145 while (!state.call_stack ().empty ())
@@ -127,6 +153,7 @@ void goto_symext::operator()(
127153 unsigned t=state.source .thread_nr +1 ;
128154 // std::cout << "********* Now executing thread " << t << '\n';
129155 state.switch_to_thread (t);
156+ symex_transition (state, state.source .pc );
130157 }
131158 }
132159
@@ -190,20 +217,20 @@ void goto_symext::symex_step(
190217 case SKIP:
191218 if (!state.guard .is_false ())
192219 target.location (state.guard .as_expr (), state.source );
193- state. source . pc ++ ;
220+ symex_transition ( state) ;
194221 break ;
195222
196223 case END_FUNCTION:
197224 // do even if state.guard.is_false() to clear out frame created
198225 // in symex_start_thread
199226 symex_end_of_function (state);
200- state. source . pc ++ ;
227+ symex_transition ( state) ;
201228 break ;
202229
203230 case LOCATION:
204231 if (!state.guard .is_false ())
205232 target.location (state.guard .as_expr (), state.source );
206- state. source . pc ++ ;
233+ symex_transition ( state) ;
207234 break ;
208235
209236 case GOTO:
@@ -219,7 +246,7 @@ void goto_symext::symex_step(
219246 symex_assume (state, tmp);
220247 }
221248
222- state. source . pc ++ ;
249+ symex_transition ( state) ;
223250 break ;
224251
225252 case ASSERT:
@@ -233,21 +260,21 @@ void goto_symext::symex_step(
233260 vcc (tmp, msg, state);
234261 }
235262
236- state. source . pc ++ ;
263+ symex_transition ( state) ;
237264 break ;
238265
239266 case RETURN:
240267 if (!state.guard .is_false ())
241268 return_assignment (state);
242269
243- state. source . pc ++ ;
270+ symex_transition ( state) ;
244271 break ;
245272
246273 case ASSIGN:
247274 if (!state.guard .is_false ())
248275 symex_assign_rec (state, to_code_assign (instruction.code ));
249276
250- state. source . pc ++ ;
277+ symex_transition ( state) ;
251278 break ;
252279
253280 case FUNCTION_CALL:
@@ -267,58 +294,58 @@ void goto_symext::symex_step(
267294 symex_function_call (goto_functions, state, deref_code);
268295 }
269296 else
270- state. source . pc ++ ;
297+ symex_transition ( state) ;
271298 break ;
272299
273300 case OTHER:
274301 if (!state.guard .is_false ())
275302 symex_other (goto_functions, state);
276303
277- state. source . pc ++ ;
304+ symex_transition ( state) ;
278305 break ;
279306
280307 case DECL:
281308 if (!state.guard .is_false ())
282309 symex_decl (state);
283310
284- state. source . pc ++ ;
311+ symex_transition ( state) ;
285312 break ;
286313
287314 case DEAD:
288315 symex_dead (state);
289- state. source . pc ++ ;
316+ symex_transition ( state) ;
290317 break ;
291318
292319 case START_THREAD:
293320 symex_start_thread (state);
294- state. source . pc ++ ;
321+ symex_transition ( state) ;
295322 break ;
296323
297324 case END_THREAD:
298325 // behaves like assume(0);
299326 if (!state.guard .is_false ())
300327 state.guard .add (false_exprt ());
301- state. source . pc ++ ;
328+ symex_transition ( state) ;
302329 break ;
303330
304331 case ATOMIC_BEGIN:
305332 symex_atomic_begin (state);
306- state. source . pc ++ ;
333+ symex_transition ( state) ;
307334 break ;
308335
309336 case ATOMIC_END:
310337 symex_atomic_end (state);
311- state. source . pc ++ ;
338+ symex_transition ( state) ;
312339 break ;
313340
314341 case CATCH:
315342 symex_catch (state);
316- state. source . pc ++ ;
343+ symex_transition ( state) ;
317344 break ;
318345
319346 case THROW:
320347 symex_throw (state);
321- state. source . pc ++ ;
348+ symex_transition ( state) ;
322349 break ;
323350
324351 case NO_INSTRUCTION_TYPE:
0 commit comments