CBMC
Loading...
Searching...
No Matches
custom_bitvector_analysis.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Field-insensitive, location-sensitive bitvector analysis
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
11
13
14#include <util/expr_util.h>
15#include <util/pointer_expr.h>
16#include <util/simplify_expr.h>
18#include <util/xml_irep.h>
19
21
22#include <iostream>
23
25 const irep_idt &identifier,
26 unsigned bit_nr,
27 modet mode)
28{
29 switch(mode)
30 {
31 case modet::SET_MUST:
32 set_bit(must_bits[identifier], bit_nr);
33 break;
34
36 clear_bit(must_bits[identifier], bit_nr);
37 break;
38
39 case modet::SET_MAY:
40 set_bit(may_bits[identifier], bit_nr);
41 break;
42
44 clear_bit(may_bits[identifier], bit_nr);
45 break;
46 }
47}
48
50 const exprt &lhs,
51 unsigned bit_nr,
52 modet mode)
53{
54 irep_idt id=object2id(lhs);
55 if(!id.empty())
56 set_bit(id, bit_nr, mode);
57}
58
60{
61 if(src.id()==ID_symbol)
62 {
63 return to_symbol_expr(src).get_identifier();
64 }
65 else if(src.id()==ID_dereference)
66 {
67 const exprt &op=to_dereference_expr(src).pointer();
68
69 if(op.id()==ID_address_of)
70 {
71 return object2id(to_address_of_expr(op).object());
72 }
73 else if(op.id()==ID_typecast)
74 {
75 irep_idt op_id=object2id(to_typecast_expr(op).op());
76
77 if(op_id.empty())
78 return irep_idt();
79 else
80 return '*'+id2string(op_id);
81 }
82 else
83 {
84 irep_idt op_id=object2id(op);
85
86 if(op_id.empty())
87 return irep_idt();
88 else
89 return '*'+id2string(op_id);
90 }
91 }
92 else if(src.id()==ID_member)
93 {
94 const auto &m=to_member_expr(src);
95 const exprt &op=m.compound();
96
97 irep_idt op_id=object2id(op);
98
99 if(op_id.empty())
100 return irep_idt();
101 else
102 return id2string(op_id)+'.'+
103 id2string(m.get_component_name());
104 }
105 else if(src.id()==ID_typecast)
106 return object2id(to_typecast_expr(src).op());
107 else
108 return irep_idt();
109}
110
112 const exprt &lhs,
113 const vectorst &vectors)
114{
115 irep_idt id=object2id(lhs);
116 if(!id.empty())
117 assign_lhs(id, vectors);
118}
119
121 const irep_idt &identifier,
122 const vectorst &vectors)
123{
124 // we erase blank ones to avoid noise
125
126 if(vectors.must_bits==0)
127 must_bits.erase(identifier);
128 else
129 must_bits[identifier]=vectors.must_bits;
130
131 if(vectors.may_bits==0)
132 may_bits.erase(identifier);
133 else
134 may_bits[identifier]=vectors.may_bits;
135}
136
139{
141
142 bitst::const_iterator may_it=may_bits.find(identifier);
143 if(may_it!=may_bits.end())
144 vectors.may_bits=may_it->second;
145
146 bitst::const_iterator must_it=must_bits.find(identifier);
147 if(must_it!=must_bits.end())
148 vectors.must_bits=must_it->second;
149
150 return vectors;
151}
152
155{
156 if(rhs.id()==ID_symbol ||
157 rhs.id()==ID_dereference)
158 {
159 const irep_idt identifier=object2id(rhs);
160 return get_rhs(identifier);
161 }
162 else if(rhs.id()==ID_typecast)
163 {
164 return get_rhs(to_typecast_expr(rhs).op());
165 }
166 else if(rhs.id()==ID_if)
167 {
168 // need to merge both
169 vectorst v_true=get_rhs(to_if_expr(rhs).true_case());
170 vectorst v_false=get_rhs(to_if_expr(rhs).false_case());
171 return merge(v_true, v_false);
172 }
173
174 return vectorst();
175}
176
178 const exprt &string_expr)
179{
180 if(string_expr.id()==ID_typecast)
182 else if(string_expr.id()==ID_address_of)
183 return get_bit_nr(to_address_of_expr(string_expr).object());
184 else if(string_expr.id()==ID_index)
185 return get_bit_nr(to_index_expr(string_expr).array());
186 else if(string_expr.id()==ID_string_constant)
187 return bits.number(to_string_constant(string_expr).value());
188 else
189 return bits.number("(unknown)");
190}
191
193 const exprt &src,
194 locationt loc)
195{
196 if(src.id()==ID_symbol)
197 {
198 std::set<exprt> result;
199 result.insert(src);
200 return result;
201 }
202 else if(src.id()==ID_dereference)
203 {
204 exprt pointer=to_dereference_expr(src).pointer();
205
206 const std::set<exprt> alias_set =
207 local_may_alias_factory(loc).get(loc, pointer);
208
209 std::set<exprt> result;
210
211 for(const auto &alias : alias_set)
212 if(alias.type().id() == ID_pointer)
213 result.insert(dereference_exprt(alias));
214
215 result.insert(src);
216
217 return result;
218 }
219 else if(src.id()==ID_typecast)
220 {
221 return aliases(to_typecast_expr(src).op(), loc);
222 }
223 else
224 return std::set<exprt>();
225}
226
229 const exprt &lhs,
230 const exprt &rhs,
232 const namespacet &ns)
233{
234 if(lhs.type().id() == ID_struct || lhs.type().id() == ID_struct_tag)
235 {
237 lhs.type().id() == ID_struct
238 ? to_struct_type(lhs.type())
240
241 // assign member-by-member
242 for(const auto &c : struct_type.components())
243 {
245 rhs_member(rhs, c);
247 }
248 }
249 else
250 {
251 // may alias other stuff
252 std::set<exprt> lhs_set=cba.aliases(lhs, from);
253
255
256 for(const auto &lhs_alias : lhs_set)
257 {
259 }
260
261 // is it a pointer?
262 if(lhs.type().id()==ID_pointer)
263 {
267 }
268 }
269}
270
272 const irep_idt &function_from,
274 const irep_idt &function_to,
276 ai_baset &ai,
277 const namespacet &ns)
278{
279 locationt from{trace_from->current_location()};
280 locationt to{trace_to->current_location()};
281
282 // upcast of ai
284 static_cast<custom_bitvector_analysist &>(ai);
285
286 const goto_programt::instructiont &instruction=*from;
287
288 switch(instruction.type())
289 {
290 case ASSIGN:
292 from, instruction.assign_lhs(), instruction.assign_rhs(), cba, ns);
293 break;
294
295 case DECL:
296 {
297 const auto &decl_symbol = instruction.decl_symbol();
298 assign_lhs(decl_symbol, vectorst());
299
300 // is it a pointer?
301 if(decl_symbol.type().id() == ID_pointer)
302 assign_lhs(dereference_exprt(decl_symbol), vectorst());
303 }
304 break;
305
306 case DEAD:
307 assign_lhs(instruction.dead_symbol(), vectorst());
308
309 // is it a pointer?
310 if(instruction.dead_symbol().type().id() == ID_pointer)
312 break;
313
314 case FUNCTION_CALL:
315 {
316 const exprt &function = instruction.call_function();
317
318 if(function.id()==ID_symbol)
319 {
320 const irep_idt &identifier=to_symbol_expr(function).get_identifier();
321
322 if(
323 identifier == CPROVER_PREFIX "set_must" ||
324 identifier == CPROVER_PREFIX "clear_must" ||
325 identifier == CPROVER_PREFIX "set_may" ||
326 identifier == CPROVER_PREFIX "clear_may")
327 {
328 if(instruction.call_arguments().size() == 2)
329 {
330 unsigned bit_nr = cba.get_bit_nr(instruction.call_arguments()[1]);
331
332 // initialize to make Visual Studio happy
333 modet mode = modet::SET_MUST;
334
335 if(identifier == CPROVER_PREFIX "set_must")
336 mode=modet::SET_MUST;
337 else if(identifier == CPROVER_PREFIX "clear_must")
339 else if(identifier == CPROVER_PREFIX "set_may")
340 mode=modet::SET_MAY;
341 else if(identifier == CPROVER_PREFIX "clear_may")
342 mode=modet::CLEAR_MAY;
343 else
345
346 exprt lhs = instruction.call_arguments()[0];
347
348 if(lhs.type().id()==ID_pointer)
349 {
350 if(
351 lhs.is_constant() &&
352 to_constant_expr(lhs).is_null_pointer()) // NULL means all
353 {
354 if(mode==modet::CLEAR_MAY)
355 {
356 for(auto &bit : may_bits)
357 clear_bit(bit.second, bit_nr);
358
359 // erase blank ones
361 }
362 else if(mode==modet::CLEAR_MUST)
363 {
364 for(auto &bit : must_bits)
365 clear_bit(bit.second, bit_nr);
366
367 // erase blank ones
369 }
370 }
371 else
372 {
374
375 // may alias other stuff
376 std::set<exprt> lhs_set=cba.aliases(deref, from);
377
378 for(const auto &l : lhs_set)
379 {
380 set_bit(l, bit_nr, mode);
381 }
382 }
383 }
384 }
385 }
386 else if(identifier=="memcpy" ||
387 identifier=="memmove")
388 {
389 if(instruction.call_arguments().size() == 3)
390 {
391 // we copy all tracked bits from op1 to op0
392 // we do not consider any bits attached to the size op2
395
397 }
398 }
399 else
400 {
401 // only if there is an actual call, i.e., we have a body
403 {
404 const code_typet &code_type=
405 to_code_type(ns.lookup(identifier).type);
406
407 code_function_callt::argumentst::const_iterator arg_it =
408 instruction.call_arguments().begin();
409 for(const auto &param : code_type.parameters())
410 {
411 const irep_idt &p_identifier=param.get_identifier();
412 if(p_identifier.empty())
413 continue;
414
415 // there may be a mismatch in the number of arguments
416 if(arg_it == instruction.call_arguments().end())
417 break;
418
419 // assignments arguments -> parameters
420 symbol_exprt p=ns.lookup(p_identifier).symbol_expr();
421 // may alias other stuff
422 std::set<exprt> lhs_set=cba.aliases(p, from);
423
425
426 for(const auto &lhs : lhs_set)
427 {
429 }
430
431 // is it a pointer?
432 if(p.type().id()==ID_pointer)
433 {
437 }
438
439 ++arg_it;
440 }
441 }
442 }
443 }
444 }
445 break;
446
447 case OTHER:
448 {
449 const auto &code = instruction.get_other();
450 const irep_idt &statement = code.get_statement();
451
452 if(
453 statement == ID_set_may || statement == ID_set_must ||
454 statement == ID_clear_may || statement == ID_clear_must)
455 {
457 code.operands().size() == 2, "set/clear_may/must has two operands");
458
459 unsigned bit_nr = cba.get_bit_nr(code.op1());
460
461 // initialize to make Visual Studio happy
462 modet mode = modet::SET_MUST;
463
464 if(statement == ID_set_must)
465 mode=modet::SET_MUST;
466 else if(statement == ID_clear_must)
468 else if(statement == ID_set_may)
469 mode=modet::SET_MAY;
470 else if(statement == ID_clear_may)
471 mode=modet::CLEAR_MAY;
472 else
474
475 exprt lhs = code.op0();
476
477 if(lhs.type().id()==ID_pointer)
478 {
479 if(
480 lhs.is_constant() &&
481 to_constant_expr(lhs).is_null_pointer()) // NULL means all
482 {
483 if(mode==modet::CLEAR_MAY)
484 {
485 for(bitst::iterator b_it=may_bits.begin();
486 b_it!=may_bits.end();
487 b_it++)
488 clear_bit(b_it->second, bit_nr);
489
490 // erase blank ones
492 }
493 else if(mode==modet::CLEAR_MUST)
494 {
495 for(bitst::iterator b_it=must_bits.begin();
496 b_it!=must_bits.end();
497 b_it++)
498 clear_bit(b_it->second, bit_nr);
499
500 // erase blank ones
502 }
503 }
504 else
505 {
507
508 // may alias other stuff
509 std::set<exprt> lhs_set=cba.aliases(deref, from);
510
511 for(const auto &l : lhs_set)
512 {
513 set_bit(l, bit_nr, mode);
514 }
515 }
516 }
517 }
518 }
519 break;
520
521 case GOTO:
522 if(has_get_must_or_may(instruction.condition()))
523 {
524 exprt guard = instruction.condition();
525
526 // Comparing iterators is safe as the target must be within the same list
527 // of instructions because this is a GOTO.
528 if(to!=from->get_target())
530
531 const exprt result2 = simplify_expr(eval(guard, cba), ns);
532
533 if(result2.is_false())
534 make_bottom();
535 }
536 break;
537
538 case CATCH:
539 case THROW:
540 DATA_INVARIANT(false, "Exceptions must be removed before analysis");
541 break;
542 case SET_RETURN_VALUE:
543 DATA_INVARIANT(false, "SET_RETURN_VALUE must be removed before analysis");
544 break;
545 case ATOMIC_BEGIN: // Ignoring is a valid over-approximation
546 case ATOMIC_END: // Ignoring is a valid over-approximation
547 case END_FUNCTION: // No action required
548 case LOCATION: // No action required
549 case START_THREAD: // Require a concurrent analysis at higher level
550 case END_THREAD: // Require a concurrent analysis at higher level
551 case SKIP: // No action required
552 case ASSERT: // No action required
553 case ASSUME: // Ignoring is a valid over-approximation
554 break;
555 case INCOMPLETE_GOTO:
557 DATA_INVARIANT(false, "Only complete instructions can be analyzed");
558 break;
559 }
560}
561
563 std::ostream &out,
564 const ai_baset &ai,
565 const namespacet &) const
566{
567 if(has_values.is_known())
568 {
569 out << has_values.to_string() << '\n';
570 return;
571 }
572
574 static_cast<const custom_bitvector_analysist &>(ai);
575
576 for(const auto &bit : may_bits)
577 {
578 out << bit.first << " MAY:";
579 bit_vectort b=bit.second;
580
581 for(unsigned i=0; b!=0; i++, b>>=1)
582 if(b&1)
583 {
584 INVARIANT(i < cba.bits.size(), "inconsistent bit widths");
585 out << ' '
586 << cba.bits[i];
587 }
588
589 out << '\n';
590 }
591
592 for(const auto &bit : must_bits)
593 {
594 out << bit.first << " MUST:";
595 bit_vectort b=bit.second;
596
597 for(unsigned i=0; b!=0; i++, b>>=1)
598 if(b&1)
599 {
600 INVARIANT(i < cba.bits.size(), "inconsistent bit widths");
601 out << ' '
602 << cba.bits[i];
603 }
604
605 out << '\n';
606 }
607}
608
613{
614 bool changed=has_values.is_false();
616
617 // first do MAY
618 bitst::iterator it=may_bits.begin();
619 for(const auto &bit : b.may_bits)
620 {
621 while(it!=may_bits.end() && it->first<bit.first)
622 ++it;
623 if(it==may_bits.end() || bit.first<it->first)
624 {
625 may_bits.insert(it, bit);
626 changed=true;
627 }
628 else if(it!=may_bits.end())
629 {
630 bit_vectort &a_bits=it->second;
632 a_bits|=bit.second;
633 if(old!=a_bits)
634 changed=true;
635
636 ++it;
637 }
638 }
639
640 // now do MUST
641 it=must_bits.begin();
642 for(auto &bit : b.must_bits)
643 {
644 while(it!=must_bits.end() && it->first<bit.first)
645 {
646 it=must_bits.erase(it);
647 changed=true;
648 }
649 if(it==must_bits.end() || bit.first<it->first)
650 {
651 must_bits.insert(it, bit);
652 changed=true;
653 }
654 else if(it!=must_bits.end())
655 {
656 bit_vectort &a_bits=it->second;
658 a_bits&=bit.second;
659 if(old!=a_bits)
660 changed=true;
661
662 ++it;
663 }
664 }
665
666 // erase blank ones
669
670 return changed;
671}
672
675{
676 for(bitst::iterator a_it=bits.begin();
677 a_it!=bits.end();
678 ) // no a_it++
679 {
680 if(a_it->second==0)
681 a_it=bits.erase(a_it);
682 else
683 a_it++;
684 }
685}
686
688{
689 if(src.id() == ID_get_must || src.id() == ID_get_may)
690 return true;
691
692 for(const auto &op : src.operands())
693 {
694 if(has_get_must_or_may(op))
695 return true;
696 }
697
698 return false;
699}
700
702 const exprt &src,
704{
705 if(src.id() == ID_get_must || src.id() == ID_get_may)
706 {
707 if(src.operands().size()==2)
708 {
709 unsigned bit_nr =
710 custom_bitvector_analysis.get_bit_nr(to_binary_expr(src).op1());
711
712 exprt pointer = to_binary_expr(src).op0();
713
714 if(pointer.type().id()!=ID_pointer)
715 return src;
716
717 if(
718 pointer.is_constant() &&
719 to_constant_expr(pointer).is_null_pointer()) // NULL means all
720 {
721 if(src.id() == ID_get_may)
722 {
723 for(const auto &bit : may_bits)
724 if(get_bit(bit.second, bit_nr))
725 return true_exprt();
726
727 return false_exprt();
728 }
729 else if(src.id() == ID_get_must)
730 {
731 return false_exprt();
732 }
733 else
734 return src;
735 }
736 else
737 {
739 get_rhs(dereference_exprt(pointer));
740
741 bool value=false;
742
743 if(src.id() == ID_get_must)
744 value=get_bit(v.must_bits, bit_nr);
745 else if(src.id() == ID_get_may)
746 value=get_bit(v.may_bits, bit_nr);
747
748 if(value)
749 return true_exprt();
750 else
751 return false_exprt();
752 }
753 }
754 else
755 return src;
756 }
757 else
758 {
759 exprt tmp=src;
762
763 return tmp;
764 }
765}
766
770
772 const goto_modelt &goto_model,
773 bool use_xml,
774 std::ostream &out)
775{
776 unsigned pass=0, fail=0, unknown=0;
777
778 for(const auto &gf_entry : goto_model.goto_functions.function_map)
779 {
780 if(!gf_entry.second.body.has_assertion())
781 continue;
782
783 // TODO this is a hard-coded hack
784 if(gf_entry.first == "__actual_thread_spawn")
785 continue;
786
787 if(!use_xml)
788 out << "******** Function " << gf_entry.first << '\n';
789
791 {
792 exprt result;
793 irep_idt description;
794
795 if(i_it->is_assert())
796 {
798 {
799 continue;
800 }
801
802 if(operator[](i_it).has_values.is_false())
803 continue;
804
805 exprt tmp = eval(i_it->condition(), i_it);
806 const namespacet ns(goto_model.symbol_table);
807 result = simplify_expr(std::move(tmp), ns);
808
809 description = i_it->source_location().get_comment();
810 }
811 else
812 continue;
813
814 if(use_xml)
815 {
816 out << "<result status=\"";
817 if(result.is_true())
818 out << "SUCCESS";
819 else if(result.is_false())
820 out << "FAILURE";
821 else
822 out << "UNKNOWN";
823 out << "\">\n";
824 out << xml(i_it->source_location());
825 out << "<description>"
826 << description
827 << "</description>\n";
828 out << "</result>\n\n";
829 }
830 else
831 {
832 out << i_it->source_location();
833 if(!description.empty())
834 out << ", " << description;
835 out << ": ";
836 const namespacet ns(goto_model.symbol_table);
837 out << from_expr(ns, gf_entry.first, result);
838 out << '\n';
839 }
840
841 if(result.is_true())
842 pass++;
843 else if(result.is_false())
844 fail++;
845 else
846 unknown++;
847 }
848
849 if(!use_xml)
850 out << '\n';
851 }
852
853 if(!use_xml)
854 out << "SUMMARY: " << pass << " pass, " << fail << " fail, "
855 << unknown << " unknown\n";
856}
static exprt guard(const exprt::operandst &guards, exprt cond)
This is the basic interface of the abstract interpreter with default implementations of the core func...
Definition ai.h:117
goto_programt::const_targett locationt
Definition ai.h:124
ai_history_baset::trace_ptrt trace_ptrt
Definition ai_domain.h:73
goto_programt::const_targett locationt
Definition ai_domain.h:72
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Base type of functions.
Definition std_types.h:583
std::set< exprt > aliases(const exprt &, locationt loc)
local_may_alias_factoryt local_may_alias_factory
exprt eval(const exprt &src, locationt loc)
void check(const goto_modelt &, bool xml, std::ostream &)
void set_bit(const exprt &, unsigned bit_nr, modet)
bool merge(const custom_bitvector_domaint &b, trace_ptrt from, trace_ptrt to)
std::map< irep_idt, bit_vectort > bitst
static irep_idt object2id(const exprt &)
void assign_struct_rec(locationt from, const exprt &lhs, const exprt &rhs, custom_bitvector_analysist &, const namespacet &)
static bool has_get_must_or_may(const exprt &)
vectorst get_rhs(const exprt &) const
static void clear_bit(bit_vectort &dest, unsigned bit_nr)
void transform(const irep_idt &function_from, trace_ptrt trace_from, const irep_idt &function_to, trace_ptrt trace_to, ai_baset &ai, const namespacet &ns) final override
how function calls are treated: a) there is an edge from each call site to the function head b) there...
void output(std::ostream &out, const ai_baset &ai, const namespacet &ns) const final override
void assign_lhs(const exprt &, const vectorst &)
void erase_blank_vectors(bitst &)
erase blank bitvectors
static bool get_bit(const bit_vectort src, unsigned bit_nr)
void make_bottom() final override
no states
exprt eval(const exprt &src, custom_bitvector_analysist &) const
Operator to dereference a pointer.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
bool empty() const
Definition dstring.h:89
Base class for all expressions.
Definition expr.h:56
bool is_true() const
Return whether the expression is a constant representing true.
Definition expr.cpp:27
bool is_false() const
Return whether the expression is a constant representing false.
Definition expr.cpp:34
exprt & op0()
Definition expr.h:133
bool is_constant() const
Return whether the expression is a constant.
Definition expr.h:212
typet & type()
Return the type of the expression.
Definition expr.h:84
operandst & operands()
Definition expr.h:94
The Boolean constant false.
Definition std_expr.h:3200
A collection of goto functions.
function_mapt function_map
symbol_tablet symbol_table
Symbol table.
Definition goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition goto_model.h:34
This class represents an instruction in the GOTO intermediate representation.
const symbol_exprt & dead_symbol() const
Get the symbol for DEAD.
const goto_instruction_codet & get_other() const
Get the statement for OTHER.
const symbol_exprt & decl_symbol() const
Get the declared symbol for DECL.
const exprt::operandst & call_arguments() const
Get the arguments of a FUNCTION_CALL.
const exprt & assign_lhs() const
Get the lhs of the assignment for ASSIGN.
const exprt & assign_rhs() const
Get the rhs of the assignment for ASSIGN.
const exprt & call_function() const
Get the function that is called for FUNCTION_CALL.
const exprt & condition() const
Get the condition of gotos, assume, assert.
goto_program_instruction_typet type() const
What kind of instruction?
const irep_idt & id() const
Definition irep.h:388
std::set< exprt > get(const goto_programt::const_targett t, const exprt &src) const
Extract member of struct or union.
Definition std_expr.h:2972
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition namespace.cpp:49
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
number_type number(const key_type &a)
Definition numbering.h:37
Structure type, corresponds to C style structs.
Definition std_types.h:231
Expression to hold a symbol (variable)
Definition std_expr.h:131
The Boolean constant true.
Definition std_expr.h:3191
bool is_known() const
Definition threeval.h:28
const char * to_string() const
Definition threeval.cpp:13
bool is_false() const
Definition threeval.h:26
static tvt unknown()
Definition threeval.h:33
#define CPROVER_PREFIX
Field-insensitive, location-sensitive bitvector analysis.
#define Forall_operands(it, expr)
Definition expr.h:27
exprt boolean_negate(const exprt &src)
negate a Boolean expression, possibly removing a not_exprt, and swapping false and true
Definition expr_util.cpp:98
Deprecated expression utility functions.
#define forall_goto_program_instructions(it, program)
@ FUNCTION_CALL
@ ATOMIC_END
@ DEAD
@ LOCATION
@ END_FUNCTION
@ ASSIGN
@ ASSERT
@ SET_RETURN_VALUE
@ ATOMIC_BEGIN
@ CATCH
@ END_THREAD
@ SKIP
@ NO_INSTRUCTION_TYPE
@ START_THREAD
@ THROW
@ DECL
@ OTHER
@ GOTO
@ INCOMPLETE_GOTO
@ ASSUME
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
API to expression classes for Pointers.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
xmlt xml(const irep_idt &property_id, const property_infot &property_info)
exprt simplify_expr(exprt src, const namespacet &ns)
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition std_expr.h:1538
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition std_expr.h:2107
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition std_expr.h:715
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition std_expr.h:2582
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition std_expr.h:3064
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition std_expr.h:3173
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:788
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:518
const string_constantt & to_string_constant(const exprt &expr)
dstringt irep_idt