CBMC
cfg.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Control Flow Graph
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #ifndef CPROVER_GOTO_PROGRAMS_CFG_H
13 #define CPROVER_GOTO_PROGRAMS_CFG_H
14 
15 #include <util/dense_integer_map.h>
16 #include <util/graph.h>
17 #include <util/std_expr.h>
18 
19 #include "goto_functions.h"
20 
22 {
23 };
24 
25 // these are the CFG nodes
26 template<class T, typename I>
27 struct cfg_base_nodet:public graph_nodet<empty_edget>, public T
28 {
31 
32  I PC;
33 };
34 
37 template <class T>
39 {
40 public:
41  std::size_t operator()(T &&t) const
42  {
43  return std::forward<T>(identity_functort{}(t));
44  }
45 };
46 
48 template <>
50 {
51 public:
52  std::size_t operator()(const goto_programt::const_targett &t) const
53  {
54  return t->location_number;
55  }
56 };
57 
83 template<class T,
84  typename P=const goto_programt,
86 class cfg_baset:public grapht< cfg_base_nodet<T, I> >
87 {
89 
90 public:
91  typedef typename base_grapht::node_indext entryt;
92  typedef typename base_grapht::nodet nodet;
93 
94  class entry_mapt final
95  {
96  typedef dense_integer_mapt<
98  entryt,
102 
103  public:
105 
106  // NOLINTNEXTLINE(readability/identifiers)
107  typedef typename data_typet::iterator iterator;
108  // NOLINTNEXTLINE(readability/identifiers)
110 
111  template <typename U>
112  const_iterator find(U &&u) const { return data.find(std::forward<U>(u)); }
113 
114  iterator begin() { return data.begin(); }
115  const_iterator begin() const { return data.begin(); }
116  const_iterator cbegin() const { return data.cbegin(); }
117 
118  iterator end() { return data.end(); }
119  const_iterator end() const { return data.end(); }
120  const_iterator cend() const { return data.cend(); }
121 
122  explicit entry_mapt(grapht< cfg_base_nodet<T, I> > &_container):
123  container(_container)
124  {
125  }
126 
128  {
129  auto e=data.insert(std::make_pair(t, 0));
130 
131  if(e.second)
132  e.first->second=container.add_node();
133 
134  return e.first->second;
135  }
136 
138  {
139  return data.at(t);
140  }
141  const entryt &at(const goto_programt::const_targett &t) const
142  {
143  return data.at(t);
144  }
145 
146  template <class Iter>
147  void setup_for_keys(Iter begin, Iter end)
148  {
150  }
151  };
152  entry_mapt entry_map;
153 
154 protected:
155  virtual void compute_edges_goto(
156  const goto_programt &goto_program,
157  const goto_programt::instructiont &instruction,
159  entryt &entry);
160 
161  virtual void compute_edges_catch(
162  const goto_programt &goto_program,
163  const goto_programt::instructiont &instruction,
165  entryt &entry);
166 
167  virtual void compute_edges_throw(
168  const goto_programt &goto_program,
169  const goto_programt::instructiont &instruction,
171  entryt &entry);
172 
173  virtual void compute_edges_start_thread(
174  const goto_programt &goto_program,
175  const goto_programt::instructiont &instruction,
177  entryt &entry);
178 
179  virtual void compute_edges_function_call(
180  const goto_functionst &goto_functions,
181  const goto_programt &goto_program,
182  const goto_programt::instructiont &instruction,
184  entryt &entry);
185 
186  void compute_edges(
187  const goto_functionst &goto_functions,
188  const goto_programt &goto_program,
189  I PC);
190 
191  void compute_edges(
192  const goto_functionst &goto_functions,
193  P &goto_program);
194 
195  void compute_edges(
196  const goto_functionst &goto_functions);
197 
198 public:
200  {
201  }
202 
203  virtual ~cfg_baset()
204  {
205  }
206 
208  const goto_functionst &goto_functions)
209  {
210  std::vector<goto_programt::const_targett> possible_keys;
211  for(const auto &id_and_function : goto_functions.function_map)
212  {
213  const auto &instructions = id_and_function.second.body.instructions;
214  possible_keys.reserve(possible_keys.size() + instructions.size());
215  for(auto it = instructions.begin(); it != instructions.end(); ++it)
216  possible_keys.push_back(it);
217  }
218  entry_map.setup_for_keys(possible_keys.begin(), possible_keys.end());
219  compute_edges(goto_functions);
220  }
221 
222  void operator()(P &goto_program)
223  {
224  goto_functionst goto_functions;
225  std::vector<goto_programt::const_targett> possible_keys;
226  const auto &instructions = goto_program.instructions;
227  possible_keys.reserve(instructions.size());
228  for(auto it = instructions.begin(); it != instructions.end(); ++it)
229  possible_keys.push_back(it);
230  entry_map.setup_for_keys(possible_keys.begin(), possible_keys.end());
231  compute_edges(goto_functions, goto_program);
232  }
233 
240  {
241  return entry_map.at(program_point);
242  }
243 
246  {
247  return (*this)[get_node_index(program_point)];
248  }
249 
251  const nodet &get_node(const goto_programt::const_targett &program_point) const
252  {
253  return (*this)[get_node_index(program_point)];
254  }
255 
259  const entry_mapt &entries() const
260  {
261  return entry_map;
262  }
263 
264  static I get_first_node(P &program)
265  {
266  return program.instructions.begin();
267  }
268  static I get_last_node(P &program)
269  {
270  return --program.instructions.end();
271  }
272  static bool nodes_empty(P &program)
273  {
274  return program.instructions.empty();
275  }
276 };
277 
278 template<class T,
279  typename P=const goto_programt,
280  typename I=goto_programt::const_targett>
281 class concurrent_cfg_baset:public virtual cfg_baset<T, P, I>
282 {
283 protected:
284  virtual void compute_edges_start_thread(
285  const goto_programt &goto_program,
286  const goto_programt::instructiont &instruction,
288  typename cfg_baset<T, P, I>::entryt &entry);
289 };
290 
291 template<class T,
292  typename P=const goto_programt,
293  typename I=goto_programt::const_targett>
294 class procedure_local_cfg_baset:public virtual cfg_baset<T, P, I>
295 {
296 protected:
297  virtual void compute_edges_function_call(
298  const goto_functionst &goto_functions,
299  const goto_programt &goto_program,
300  const goto_programt::instructiont &instruction,
302  typename cfg_baset<T, P, I>::entryt &entry);
303 };
304 
305 template<class T,
306  typename P=const goto_programt,
307  typename I=goto_programt::const_targett>
309  public concurrent_cfg_baset<T, P, I>,
310  public procedure_local_cfg_baset<T, P, I>
311 {
312 };
313 
314 template<class T, typename P, typename I>
316  const goto_programt &goto_program,
317  const goto_programt::instructiont &instruction,
319  entryt &entry)
320 {
321  if(
322  next_PC != goto_program.instructions.end() &&
323  !instruction.condition().is_true())
324  {
325  this->add_edge(entry, entry_map[next_PC]);
326  }
327 
328  this->add_edge(entry, entry_map[instruction.get_target()]);
329 }
330 
331 template<class T, typename P, typename I>
333  const goto_programt &goto_program,
334  const goto_programt::instructiont &instruction,
336  entryt &entry)
337 {
338  if(next_PC!=goto_program.instructions.end())
339  this->add_edge(entry, entry_map[next_PC]);
340 
341  // Not ideal, but preserves targets
342  // Ideally, the throw statements should have those as successors
343 
344  for(const auto &t : instruction.targets)
345  if(t!=goto_program.instructions.end())
346  this->add_edge(entry, entry_map[t]);
347 }
348 
349 template<class T, typename P, typename I>
351  const goto_programt &,
354  entryt &)
355 {
356  // no (trivial) successors
357 }
358 
359 template<class T, typename P, typename I>
361  const goto_programt &goto_program,
364  entryt &entry)
365 {
366  if(next_PC!=goto_program.instructions.end())
367  this->add_edge(entry, entry_map[next_PC]);
368 }
369 
370 template<class T, typename P, typename I>
372  const goto_programt &goto_program,
373  const goto_programt::instructiont &instruction,
375  typename cfg_baset<T, P, I>::entryt &entry)
376 {
378  goto_program,
379  instruction,
380  next_PC,
381  entry);
382 
383  this->add_edge(entry, this->entry_map[instruction.get_target()]);
384 }
385 
386 template<class T, typename P, typename I>
388  const goto_functionst &goto_functions,
389  const goto_programt &goto_program,
390  const goto_programt::instructiont &instruction,
392  entryt &entry)
393 {
394  const exprt &function = instruction.call_function();
395 
396  if(function.id()!=ID_symbol)
397  return;
398 
399  const irep_idt &identifier=
400  to_symbol_expr(function).get_identifier();
401 
402  goto_functionst::function_mapt::const_iterator f_it=
403  goto_functions.function_map.find(identifier);
404 
405  if(f_it!=goto_functions.function_map.end() &&
406  f_it->second.body_available())
407  {
408  // get the first instruction
410  f_it->second.body.instructions.begin();
411 
413  f_it->second.body.instructions.end();
414 
415  goto_programt::const_targett last_it=e_it; last_it--;
416 
417  if(i_it!=e_it)
418  {
419  // nonempty function
420  this->add_edge(entry, entry_map[i_it]);
421 
422  // add the last instruction as predecessor of the return location
423  if(next_PC!=goto_program.instructions.end())
424  this->add_edge(entry_map[last_it], entry_map[next_PC]);
425  }
426  else if(next_PC!=goto_program.instructions.end())
427  {
428  // empty function
429  this->add_edge(entry, entry_map[next_PC]);
430  }
431  }
432  else if(next_PC!=goto_program.instructions.end())
433  this->add_edge(entry, entry_map[next_PC]);
434 }
435 
436 template<class T, typename P, typename I>
438  const goto_functionst &,
439  const goto_programt &goto_program,
440  const goto_programt::instructiont &instruction,
442  typename cfg_baset<T, P, I>::entryt &entry)
443 {
444  const exprt &function = instruction.call_function();
445 
446  if(function.id()!=ID_symbol)
447  return;
448 
449  if(next_PC!=goto_program.instructions.end())
450  this->add_edge(entry, this->entry_map[next_PC]);
451 }
452 
453 template<class T, typename P, typename I>
455  const goto_functionst &goto_functions,
456  const goto_programt &goto_program,
457  I PC)
458 {
459  const goto_programt::instructiont &instruction=*PC;
460  entryt entry=entry_map[PC];
461  (*this)[entry].PC=PC;
462  goto_programt::const_targett next_PC(PC);
463  next_PC++;
464 
465  // compute forward edges first
466  switch(instruction.type())
467  {
468  case GOTO:
469  compute_edges_goto(goto_program, instruction, next_PC, entry);
470  break;
471 
472  case CATCH:
473  compute_edges_catch(goto_program, instruction, next_PC, entry);
474  break;
475 
476  case THROW:
477  compute_edges_throw(goto_program, instruction, next_PC, entry);
478  break;
479 
480  case START_THREAD:
481  compute_edges_start_thread(
482  goto_program,
483  instruction,
484  next_PC,
485  entry);
486  break;
487 
488  case FUNCTION_CALL:
489  compute_edges_function_call(
490  goto_functions,
491  goto_program,
492  instruction,
493  next_PC,
494  entry);
495  break;
496 
497  case END_THREAD:
498  case END_FUNCTION:
499  // no successor
500  break;
501 
502  case ASSUME:
503  // false guard -> no successor
504  if(instruction.condition().is_false())
505  break;
506 
507  case ASSIGN:
508  case ASSERT:
509  case OTHER:
510  case SET_RETURN_VALUE:
511  case SKIP:
512  case LOCATION:
513  case ATOMIC_BEGIN:
514  case ATOMIC_END:
515  case DECL:
516  case DEAD:
517  if(next_PC!=goto_program.instructions.end())
518  this->add_edge(entry, entry_map[next_PC]);
519  break;
520 
521  case NO_INSTRUCTION_TYPE:
522  case INCOMPLETE_GOTO:
523  UNREACHABLE;
524  break;
525  }
526 }
527 
528 template<class T, typename P, typename I>
530  const goto_functionst &goto_functions,
531  P &goto_program)
532 {
533  for(I it=goto_program.instructions.begin();
534  it!=goto_program.instructions.end();
535  ++it)
536  compute_edges(goto_functions, goto_program, it);
537 }
538 
539 template<class T, typename P, typename I>
541  const goto_functionst &goto_functions)
542 {
543  for(const auto &gf_entry : goto_functions.function_map)
544  {
545  if(gf_entry.second.body_available())
546  compute_edges(goto_functions, gf_entry.second.body);
547  }
548 }
549 
550 #endif // CPROVER_GOTO_PROGRAMS_CFG_H
cfg_instruction_to_dense_integert
Functor to convert cfg nodes into dense integers, used by cfg_baset.
Definition: cfg.h:38
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
cfg_baset::entry_mapt::find
const_iterator find(U &&u) const
Definition: cfg.h:112
dense_integer_mapt::setup_for_keys
void setup_for_keys(Iter first, Iter last)
Set the keys that are allowed to be used in this container.
Definition: dense_integer_map.h:227
SET_RETURN_VALUE
@ SET_RETURN_VALUE
Definition: goto_program.h:45
cfg_baset::entry_mapt::setup_for_keys
void setup_for_keys(Iter begin, Iter end)
Definition: cfg.h:147
cfg_baset::~cfg_baset
virtual ~cfg_baset()
Definition: cfg.h:203
cfg_baset::entry_mapt::data_typet
dense_integer_mapt< goto_programt::const_targett, entryt, cfg_instruction_to_dense_integert< goto_programt::const_targett > > data_typet
Definition: cfg.h:100
dense_integer_mapt< goto_programt::const_targett, entryt, cfg_instruction_to_dense_integert< goto_programt::const_targett > >::const_iterator
iterator_templatet< typename backing_storet::const_iterator, const typename backing_storet::value_type > const_iterator
const iterator.
Definition: dense_integer_map.h:213
cfg_baset::get_node
const nodet & get_node(const goto_programt::const_targett &program_point) const
Get the CFG graph node relating to program_point.
Definition: cfg.h:251
procedure_local_cfg_baset::compute_edges_function_call
virtual void compute_edges_function_call(const goto_functionst &goto_functions, const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, typename cfg_baset< T, P, I >::entryt &entry)
Definition: cfg.h:437
cfg_baset::operator()
void operator()(P &goto_program)
Definition: cfg.h:222
cfg_base_nodet::PC
I PC
Definition: cfg.h:32
dense_integer_mapt::insert
std::pair< iterator, bool > insert(const std::pair< const K, V > &pair)
Definition: dense_integer_map.h:289
cfg_baset::entryt
base_grapht::node_indext entryt
Definition: cfg.h:91
concurrent_cfg_baset
Definition: cfg.h:281
grapht
A generic directed graph with a parametric node type.
Definition: graph.h:166
grapht::add_node
node_indext add_node(arguments &&... values)
Definition: graph.h:180
cfg_instruction_to_dense_integert< goto_programt::const_targett >
GOTO-instruction to location number functor.
Definition: cfg.h:49
cfg_baset::entry_mapt::container
grapht< cfg_base_nodet< T, I > > & container
Definition: cfg.h:104
dense_integer_mapt::at
const V & at(const K &key) const
Definition: dense_integer_map.h:269
exprt
Base class for all expressions.
Definition: expr.h:55
cfg_baset::entry_mapt::operator[]
entryt & operator[](const goto_programt::const_targett &t)
Definition: cfg.h:127
goto_programt::instructiont::targets
targetst targets
The list of successor instructions.
Definition: goto_program.h:394
empty_cfg_nodet
Definition: cfg.h:21
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:34
cfg_baset::compute_edges_throw
virtual void compute_edges_throw(const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, entryt &entry)
Definition: cfg.h:350
cfg_baset::entry_mapt::at
const entryt & at(const goto_programt::const_targett &t) const
Definition: cfg.h:141
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
cfg_baset::entries
const entry_mapt & entries() const
Get a map from program points to their corresponding node indices.
Definition: cfg.h:259
cfg_baset::compute_edges_start_thread
virtual void compute_edges_start_thread(const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, entryt &entry)
Definition: cfg.h:360
exprt::is_false
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:43
grapht< cfg_base_nodet< cfg_nodet, goto_programt::const_targett > >::node_indext
nodet::node_indext node_indext
Definition: graph.h:173
cfg_baset::get_last_node
static I get_last_node(P &program)
Definition: cfg.h:268
cfg_baset::entry_mapt::data
data_typet data
Definition: cfg.h:101
procedure_local_concurrent_cfg_baset
Definition: cfg.h:308
cfg_baset::cfg_baset
cfg_baset()
Definition: cfg.h:199
THROW
@ THROW
Definition: goto_program.h:50
cfg_baset::get_node
nodet & get_node(const goto_programt::const_targett &program_point)
Get the CFG graph node relating to program_point.
Definition: cfg.h:245
GOTO
@ GOTO
Definition: goto_program.h:34
cfg_baset::entry_mapt
Definition: cfg.h:94
goto_programt::instructiont::type
goto_program_instruction_typet type() const
What kind of instruction?
Definition: goto_program.h:351
cfg_base_nodet::edgest
graph_nodet< empty_edget >::edgest edgest
Definition: cfg.h:30
cfg_baset::compute_edges_function_call
virtual void compute_edges_function_call(const goto_functionst &goto_functions, const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, entryt &entry)
Definition: cfg.h:387
cfg_instruction_to_dense_integert< goto_programt::const_targett >::operator()
std::size_t operator()(const goto_programt::const_targett &t) const
Definition: cfg.h:52
identity_functort
Identity functor. When we use C++20 this can be replaced with std::identity.
Definition: dense_integer_map.h:23
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
cfg_baset::get_node_index
entryt get_node_index(const goto_programt::const_targett &program_point) const
Get the graph node index for program_point.
Definition: cfg.h:239
dense_integer_mapt::end
iterator end()
Definition: dense_integer_map.h:326
dense_integer_mapt::cbegin
const_iterator cbegin() const
Definition: dense_integer_map.h:341
NO_INSTRUCTION_TYPE
@ NO_INSTRUCTION_TYPE
Definition: goto_program.h:33
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
cfg_baset::nodes_empty
static bool nodes_empty(P &program)
Definition: cfg.h:272
OTHER
@ OTHER
Definition: goto_program.h:37
cfg_baset::compute_edges
void compute_edges(const goto_functionst &goto_functions, const goto_programt &goto_program, I PC)
Definition: cfg.h:454
cfg_baset::entry_mapt::end
const_iterator end() const
Definition: cfg.h:119
cfg_baset::entry_mapt::at
entryt & at(const goto_programt::const_targett &t)
Definition: cfg.h:137
END_FUNCTION
@ END_FUNCTION
Definition: goto_program.h:42
SKIP
@ SKIP
Definition: goto_program.h:38
cfg_baset::entry_mapt::entry_mapt
entry_mapt(grapht< cfg_base_nodet< T, I > > &_container)
Definition: cfg.h:122
cfg_baset::entry_mapt::cbegin
const_iterator cbegin() const
Definition: cfg.h:116
dense_integer_mapt< goto_programt::const_targett, entryt, cfg_instruction_to_dense_integert< goto_programt::const_targett > >::iterator
iterator_templatet< typename backing_storet::iterator, typename backing_storet::value_type > iterator
iterator.
Definition: dense_integer_map.h:206
cfg_baset::entry_map
entry_mapt entry_map
Definition: cfg.h:152
cfg_baset
A multi-procedural control flow graph (CFG) whose nodes store references to instructions in a GOTO pr...
Definition: cfg.h:86
goto_programt::instructions
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:592
ASSIGN
@ ASSIGN
Definition: goto_program.h:46
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
cfg_baset::entry_mapt::const_iterator
data_typet::const_iterator const_iterator
Definition: cfg.h:109
cfg_instruction_to_dense_integert::operator()
std::size_t operator()(T &&t) const
Definition: cfg.h:41
CATCH
@ CATCH
Definition: goto_program.h:51
cfg_baset::nodet
base_grapht::nodet nodet
Definition: cfg.h:92
graph.h
cfg_baset::base_grapht
grapht< cfg_base_nodet< T, I > > base_grapht
Definition: cfg.h:88
DECL
@ DECL
Definition: goto_program.h:47
graph_nodet
This class represents a node in a directed graph.
Definition: graph.h:34
dense_integer_map.h
cfg_baset::compute_edges_goto
virtual void compute_edges_goto(const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, entryt &entry)
Definition: cfg.h:315
ASSUME
@ ASSUME
Definition: goto_program.h:35
procedure_local_cfg_baset
Definition: cfg.h:294
cfg_base_nodet::edget
graph_nodet< empty_edget >::edget edget
Definition: cfg.h:29
START_THREAD
@ START_THREAD
Definition: goto_program.h:39
FUNCTION_CALL
@ FUNCTION_CALL
Definition: goto_program.h:49
goto_functions.h
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
cfg_base_nodet
Definition: cfg.h:27
ATOMIC_END
@ ATOMIC_END
Definition: goto_program.h:44
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
goto_programt::instructiont::condition
const exprt & condition() const
Get the condition of gotos, assume, assert.
Definition: goto_program.h:373
DEAD
@ DEAD
Definition: goto_program.h:48
cfg_baset::compute_edges_catch
virtual void compute_edges_catch(const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, entryt &entry)
Definition: cfg.h:332
cfg_baset::entry_mapt::begin
iterator begin()
Definition: cfg.h:114
cfg_baset::operator()
void operator()(const goto_functionst &goto_functions)
Definition: cfg.h:207
ATOMIC_BEGIN
@ ATOMIC_BEGIN
Definition: goto_program.h:43
dense_integer_mapt::begin
iterator begin()
Definition: dense_integer_map.h:321
LOCATION
@ LOCATION
Definition: goto_program.h:41
ASSERT
@ ASSERT
Definition: goto_program.h:36
goto_programt::instructiont
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:180
std_expr.h
cfg_baset::entry_mapt::cend
const_iterator cend() const
Definition: cfg.h:120
dense_integer_mapt::cend
const_iterator cend() const
Definition: dense_integer_map.h:346
cfg_baset::entry_mapt::begin
const_iterator begin() const
Definition: cfg.h:115
concurrent_cfg_baset::compute_edges_start_thread
virtual void compute_edges_start_thread(const goto_programt &goto_program, const goto_programt::instructiont &instruction, goto_programt::const_targett next_PC, typename cfg_baset< T, P, I >::entryt &entry)
Definition: cfg.h:371
cfg_baset::entry_mapt::iterator
data_typet::iterator iterator
Definition: cfg.h:107
goto_programt::instructiont::call_function
const exprt & call_function() const
Get the function that is called for FUNCTION_CALL.
Definition: goto_program.h:279
goto_programt::instructiont::get_target
targett get_target() const
Returns the first (and only) successor for the usual case of a single target.
Definition: goto_program.h:398
END_THREAD
@ END_THREAD
Definition: goto_program.h:40
INCOMPLETE_GOTO
@ INCOMPLETE_GOTO
Definition: goto_program.h:52
cfg_baset::get_first_node
static I get_first_node(P &program)
Definition: cfg.h:264
cfg_baset::entry_mapt::end
iterator end()
Definition: cfg.h:118
dense_integer_mapt
A map type that is backed by a vector, which relies on the ability to (a) see the keys that might be ...
Definition: dense_integer_map.h:53