-
Notifications
You must be signed in to change notification settings - Fork 274
abstract_environmentt::eval rework #5644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
c372994
de45be5
75e45c7
af3eb52
e62d4f1
8798ccc
474479c
405bab3
ba9dbf5
a5f16cf
1407cd4
7af43f3
a983bd5
c8f3e48
97b6d87
7ead4af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
CORE | ||
union.c | ||
--variable-sensitivity --vsd --verify | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^\[main.assertion.1\] line 13 x.a==0: UNKNOWN$ | ||
^\[main.assertion.2\] line 14 x.a==1: UNKNOWN$ | ||
^\[main.assertion.3\] line 15 x.b==0: UNKNOWN$ | ||
^\[main.assertion.4\] line 16 x.b==1: UNKNOWN$ | ||
^\[main.assertion.5\] line 19 x.a==0: UNKNOWN$ | ||
^\[main.assertion.6\] line 20 x.a==1: UNKNOWN$ | ||
^\[main.assertion.7\] line 21 x.b==0: UNKNOWN$ | ||
^\[main.assertion.8\] line 22 x.b==1: UNKNOWN$ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With a "most recently written" abstraction for unions it should be possible to turn about half of these into successes but for now all unknown is the best that can be done. |
||
-- | ||
^warning: ignoring |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <assert.h> | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
// Test if we can represent constant structs | ||
union union_struct { | ||
int a; | ||
int b; | ||
}; | ||
|
||
union union_struct x = {0}; | ||
x.a = 0; | ||
__CPROVER_assert(x.a == 0, "x.a==0"); | ||
__CPROVER_assert(x.a == 1, "x.a==1"); | ||
__CPROVER_assert(x.b == 0, "x.b==0"); | ||
__CPROVER_assert(x.b == 1, "x.b==1"); | ||
|
||
x.b = 1; | ||
__CPROVER_assert(x.a == 0, "x.a==0"); | ||
__CPROVER_assert(x.a == 1, "x.a==1"); | ||
__CPROVER_assert(x.b == 0, "x.b==0"); | ||
__CPROVER_assert(x.b == 1, "x.b==1"); | ||
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,11 @@ | |
# include <iostream> | ||
#endif | ||
|
||
std::vector<abstract_object_pointert> eval_operands( | ||
const exprt &expr, | ||
const abstract_environmentt &env, | ||
const namespacet &ns); | ||
|
||
abstract_object_pointert | ||
abstract_environmentt::eval(const exprt &expr, const namespacet &ns) const | ||
{ | ||
|
@@ -51,14 +56,15 @@ abstract_environmentt::eval(const exprt &expr, const namespacet &ns) const | |
return found_symbol_value; | ||
} | ||
} | ||
else if(simplified_id == ID_member) | ||
else if( | ||
martin-cs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
simplified_id == ID_member || simplified_id == ID_index || | ||
simplified_id == ID_dereference) | ||
{ | ||
member_exprt member_expr(to_member_expr(simplified_expr)); | ||
auto access_expr = simplified_expr; | ||
auto target = eval(access_expr.operands()[0], ns); | ||
|
||
const exprt &parent = member_expr.compound(); | ||
|
||
abstract_object_pointert parent_abstract_object = eval(parent, ns); | ||
return parent_abstract_object->read(*this, member_expr, ns); | ||
return target->expression_transform( | ||
access_expr, eval_operands(access_expr, *this, ns), *this, ns); | ||
} | ||
else if(simplified_id == ID_address_of) | ||
{ | ||
|
@@ -68,35 +74,12 @@ abstract_environmentt::eval(const exprt &expr, const namespacet &ns) const | |
// Store the abstract object in the pointer | ||
return pointer_object; | ||
} | ||
else if(simplified_id == ID_dereference) | ||
{ | ||
dereference_exprt dereference(to_dereference_expr(simplified_expr)); | ||
abstract_object_pointert pointer_abstract_object = | ||
eval(dereference.pointer(), ns); | ||
|
||
return pointer_abstract_object->read(*this, nil_exprt(), ns); | ||
} | ||
else if(simplified_id == ID_index) | ||
{ | ||
index_exprt index_expr(to_index_expr(simplified_expr)); | ||
abstract_object_pointert array_abstract_object = | ||
eval(index_expr.array(), ns); | ||
|
||
return array_abstract_object->read(*this, index_expr, ns); | ||
} | ||
else if(simplified_id == ID_array) | ||
else if( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes; these are all basically the same constant case. |
||
simplified_id == ID_array || simplified_id == ID_struct || | ||
simplified_id == ID_constant) | ||
{ | ||
return abstract_object_factory(simplified_expr.type(), simplified_expr, ns); | ||
} | ||
else if(simplified_id == ID_struct) | ||
{ | ||
return abstract_object_factory(simplified_expr.type(), simplified_expr, ns); | ||
} | ||
else if(simplified_id == ID_constant) | ||
{ | ||
return abstract_object_factory( | ||
simplified_expr.type(), to_constant_expr(simplified_expr), ns); | ||
} | ||
else | ||
{ | ||
// No special handling required by the abstract environment | ||
|
@@ -448,14 +431,8 @@ abstract_object_pointert abstract_environmentt::eval_expression( | |
abstract_object_pointert eval_obj = | ||
abstract_object_factory(e.type(), ns, true); | ||
|
||
std::vector<abstract_object_pointert> operands; | ||
|
||
for(const auto &op : e.operands()) | ||
{ | ||
operands.push_back(eval(op, ns)); | ||
} | ||
|
||
return eval_obj->expression_transform(e, operands, *this, ns); | ||
return eval_obj->expression_transform( | ||
e, eval_operands(e, *this, ns), *this, ns); | ||
} | ||
|
||
void abstract_environmentt::erase(const symbol_exprt &expr) | ||
|
@@ -527,3 +504,16 @@ abstract_environmentt::gather_statistics(const namespacet &ns) const | |
} | ||
return statistics; | ||
} | ||
|
||
std::vector<abstract_object_pointert> eval_operands( | ||
const exprt &expr, | ||
const abstract_environmentt &env, | ||
const namespacet &ns) | ||
{ | ||
std::vector<abstract_object_pointert> operands; | ||
|
||
for(const auto &op : expr.operands()) | ||
operands.push_back(env.eval(op, ns)); | ||
|
||
return operands; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
--vsd
and--variable-sensitivity
should do the same thing. One was for backwards compatibility.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please can you go down to just one of these two?