Skip to content

Commit 6d86395

Browse files
committed
Consider local write set in subset check
Signed-off-by: Felipe R. Monteiro <[email protected]>
1 parent e9cfb2c commit 6d86395

File tree

3 files changed

+26
-23
lines changed

3 files changed

+26
-23
lines changed

src/goto-instrument/contracts/assigns.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ assigns_clauset::assigns_clauset(
9292
{
9393
for(const auto &target_expr : expr.operands())
9494
{
95-
add_global_write_set(target_expr);
95+
add_to_global_write_set(target_expr);
9696
}
9797
}
9898

99-
void assigns_clauset::add_global_write_set(const exprt &target_expr)
99+
void assigns_clauset::add_to_global_write_set(const exprt &target_expr)
100100
{
101101
auto insertion_succeeded =
102102
global_write_set.emplace(*this, target_expr).second;
@@ -110,24 +110,17 @@ void assigns_clauset::add_global_write_set(const exprt &target_expr)
110110
}
111111
}
112112

113-
void assigns_clauset::remove_global_write_set(const exprt &target_expr)
113+
void assigns_clauset::remove_from_global_write_set(const exprt &target_expr)
114114
{
115115
global_write_set.erase(targett(*this, target_expr));
116116
}
117117

118-
void assigns_clauset::add_local_write_set(const exprt &expr)
118+
void assigns_clauset::add_to_local_write_set(const exprt &expr)
119119
{
120-
auto insertion_succeeded = local_write_set.emplace(*this, expr).second;
121-
122-
if(!insertion_succeeded)
123-
{
124-
log.warning() << "Ignored duplicate expression '"
125-
<< from_expr(ns, expr.id(), expr) << "' in assigns clause at "
126-
<< expr.source_location().as_string() << messaget::eom;
127-
}
120+
local_write_set.emplace(*this, expr);
128121
}
129122

130-
void assigns_clauset::remove_local_write_set(const exprt &expr)
123+
void assigns_clauset::remove_from_local_write_set(const exprt &expr)
131124
{
132125
local_write_set.erase(targett(*this, expr));
133126
}
@@ -173,6 +166,11 @@ exprt assigns_clauset::generate_subset_check(
173166
if(subassigns.global_write_set.empty())
174167
return true_exprt();
175168

169+
INVARIANT(
170+
subassigns.local_write_set.empty(),
171+
"Local write set for function calls should be empty at this point.\n" +
172+
subassigns.location.as_string());
173+
176174
exprt result = true_exprt();
177175
for(const auto &subtarget : subassigns.global_write_set)
178176
{
@@ -188,6 +186,11 @@ exprt assigns_clauset::generate_subset_check(
188186
current_subtarget_found_conditions.push_back(
189187
target.generate_containment_check(subtarget.address));
190188
}
189+
for(const auto &target : local_write_set)
190+
{
191+
current_subtarget_found_conditions.push_back(
192+
target.generate_containment_check(subtarget.address));
193+
}
191194

192195
auto current_subtarget_found = or_exprt(
193196
not_exprt(validity_check),

src/goto-instrument/contracts/assigns.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ class assigns_clauset
5252

5353
assigns_clauset(const exprt &, const messaget &, const namespacet &);
5454

55-
void add_global_write_set(const exprt &);
56-
void remove_global_write_set(const exprt &);
57-
void add_local_write_set(const exprt &);
58-
void remove_local_write_set(const exprt &);
55+
void add_to_global_write_set(const exprt &);
56+
void remove_from_global_write_set(const exprt &);
57+
void add_to_local_write_set(const exprt &);
58+
void remove_from_local_write_set(const exprt &);
5959

6060
goto_programt generate_havoc_code() const;
6161
exprt generate_containment_check(const exprt &) const;

src/goto-instrument/contracts/contracts.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ void code_contractst::instrument_assign_statement(
689689
lhs_sym.is_static_lifetime &&
690690
lhs_sym.location.get_function() ==
691691
instruction_iterator->source_location.get_function())
692-
assigns_clause.add_local_write_set(lhs);
692+
assigns_clause.add_to_local_write_set(lhs);
693693
}
694694

695695
goto_programt alias_assertion;
@@ -737,13 +737,13 @@ void code_contractst::instrument_call_statement(
737737
instrument_assign_statement(
738738
instruction_iterator, program, assigns_clause);
739739
const exprt &lhs = instruction_iterator->assign_lhs();
740-
assigns_clause.add_local_write_set(dereference_exprt(lhs));
740+
assigns_clause.add_to_local_write_set(dereference_exprt(lhs));
741741
}
742742
return; // assume malloc edits no pre-existing memory objects.
743743
}
744744
else if(called_name == "free")
745745
{
746-
assigns_clause.remove_local_write_set(dereference_exprt(
746+
assigns_clause.remove_from_local_write_set(dereference_exprt(
747747
to_typecast_expr(instruction_iterator->call_arguments().front()).op()));
748748
return;
749749
}
@@ -894,7 +894,7 @@ bool code_contractst::check_frame_conditions_function(const irep_idt &function)
894894
// Adds formal parameters to freely assignable set
895895
for(auto &parameter : to_code_type(target.type).parameters())
896896
{
897-
assigns.add_local_write_set(
897+
assigns.add_to_local_write_set(
898898
ns.lookup(parameter.get_identifier()).symbol_expr());
899899
}
900900

@@ -915,7 +915,7 @@ void code_contractst::check_frame_conditions(
915915
if(instruction_it->is_decl())
916916
{
917917
// Local variables are always freely assignable
918-
assigns.add_local_write_set(instruction_it->get_decl().symbol());
918+
assigns.add_to_local_write_set(instruction_it->get_decl().symbol());
919919
}
920920
else if(instruction_it->is_assign())
921921
{
@@ -933,7 +933,7 @@ void code_contractst::check_frame_conditions(
933933
}
934934
else if(instruction_it->is_dead())
935935
{
936-
assigns.remove_local_write_set(instruction_it->get_dead().symbol());
936+
assigns.remove_from_local_write_set(instruction_it->get_dead().symbol());
937937
}
938938
}
939939
}

0 commit comments

Comments
 (0)