-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathinvariant_set_domain.cpp
95 lines (77 loc) · 2.3 KB
/
invariant_set_domain.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*******************************************************************\
Module: Invariant Set Domain
Author: Daniel Kroening, [email protected]
\*******************************************************************/
/// \file
/// Invariant Set Domain
#include "invariant_set_domain.h"
#include <util/expr_util.h>
#include <util/simplify_expr.h>
void invariant_set_domaint::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)
{
locationt from_l(trace_from->current_location());
locationt to_l(trace_to->current_location());
switch(from_l->type())
{
case GOTO:
{
// Comparing iterators is safe as the target must be within the same list
// of instructions because this is a GOTO.
exprt tmp(from_l->condition());
if(std::next(from_l) == to_l)
tmp = boolean_negate(tmp);
simplify(tmp, ns);
invariant_set.strengthen(tmp);
}
break;
case ASSERT:
case ASSUME:
{
exprt tmp(from_l->condition());
simplify(tmp, ns);
invariant_set.strengthen(tmp);
}
break;
case SET_RETURN_VALUE:
// ignore
break;
case ASSIGN:
invariant_set.assignment(from_l->assign_lhs(), from_l->assign_rhs());
break;
case OTHER:
if(from_l->get_other().is_not_nil())
invariant_set.apply_code(from_l->code());
break;
case DECL:
invariant_set.apply_code(from_l->code());
break;
case FUNCTION_CALL:
invariant_set.apply_code(from_l->code());
break;
case START_THREAD:
invariant_set.make_threaded();
break;
case CATCH:
case THROW:
DATA_INVARIANT(false, "Exceptions must be removed before analysis");
break;
case DEAD: // No action required
case ATOMIC_BEGIN: // Ignoring is a valid over-approximation
case ATOMIC_END: // Ignoring is a valid over-approximation
case END_FUNCTION: // No action required
case LOCATION: // No action required
case END_THREAD: // Require a concurrent analysis at higher level
case SKIP: // No action required
break;
case INCOMPLETE_GOTO:
case NO_INSTRUCTION_TYPE:
DATA_INVARIANT(false, "Only complete instructions can be analyzed");
break;
}
}