Skip to content

Commit b497aec

Browse files
committed
Added LVSA method for singularity check
Added LVSA method for singularity check that overrides the one from VSA, considers the recency of dynamic-objects. Replaced the old free function with calls to the above described LVSA method. The singularity check is now done at the set of expressions level. Dropped the taint_algorithm_computing_summary_of_functiont::compute_aliased_numbers_of_lvalue() method.
1 parent 01c8c31 commit b497aec

File tree

5 files changed

+133
-77
lines changed

5 files changed

+133
-77
lines changed

cbmc

src/pointer-analysis/local_value_set_analysis.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,39 @@ static void get_reachable_objects(
341341
}
342342
}
343343

344+
/*******************************************************************\
345+
346+
Function: local_value_set_analysist::is_singular
347+
348+
Inputs: The set of expressions to check.
349+
350+
Outputs: true, if the set contains only one element and
351+
that element is either a most-recent-allocation
352+
dynamic-object or a symbol (treated in the call
353+
to the base class).
354+
false, otherwise.
355+
356+
Purpose: Get whether a set of expressions can have a strong update
357+
or not.
358+
359+
\*******************************************************************/
360+
361+
bool local_value_set_analysist::is_singular(const std::set<exprt> &values)
362+
{
363+
if(values.size()!=1)
364+
return false;
365+
366+
const exprt &object=*values.begin();
367+
if(object.id()==ID_dynamic_object)
368+
{
369+
return to_dynamic_object_expr(object).get_recency()==
370+
dynamic_object_exprt::recencyt::MOST_RECENT_ALLOCATION;
371+
}
372+
373+
// Otherwise fall back to base:
374+
return baset::is_singular(values);
375+
}
376+
344377
static void escape_analysis(
345378
const std::vector<local_value_sett::valuest::const_iterator>& values,
346379
std::set<unsigned long>& escaped)

src/pointer-analysis/local_value_set_analysis.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class local_value_set_analysist
8888

8989
void save_summary(const goto_programt&);
9090

91+
bool is_singular(const std::set<exprt> &);
92+
9193
size_t nstubs;
9294
size_t nstub_assignments;
9395

src/taint-analysis/taint_summary.cpp

Lines changed: 97 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,13 @@ static bool is_pure_local(const exprt &lvalue, const symbol_utilst &nsu)
4949
!nsu.is_static(lvalue);
5050
}
5151

52-
// Get whether an expression refers to a unique dynamic lvalue, as
53-
// opposed to e.g. a dynamic object expression, which refers to the
54-
// general case of objects allocated (at a particular program point)
55-
static bool is_expr_singular_object(
56-
const object_numberingt &numbering, taint_lvalue_numbert lvalue_num)
57-
{
58-
return get_underlying_object(numbering.at(lvalue_num)).id()==ID_symbol;
59-
}
60-
61-
6252
////////////////////////////////////////////////////////////////////////////////
6353
///
6454
/// LVSA related stuff : Should be moved to LVSA!
6555
///
6656
////////////////////////////////////////////////////////////////////////////////
6757

6858

69-
static void collect_lvsa_access_paths(
70-
exprt const& e,
71-
namespacet const& ns,
72-
lvalue_numbers_sett& result,
73-
local_value_set_analysist& lvsa,
74-
instruction_iteratort const& instit,
75-
object_numberingt&);
76-
7759
struct parameter_matches_id {
7860
parameter_matches_id(const irep_idt& _id) : id(_id) {}
7961
bool operator()(const code_typet::parametert& p) const
@@ -167,11 +149,21 @@ static exprt transform_external_objects(const exprt& e)
167149
static void collect_lvsa_access_paths(
168150
exprt const& querye_in,
169151
namespacet const& ns,
170-
lvalue_numbers_sett& result,
171152
local_value_set_analysist& lvsa,
172153
instruction_iteratort const& instit,
173-
object_numberingt& taint_object_numbering)
154+
std::set<exprt> &result)
174155
{
156+
if(querye_in.id()==ID_side_effect)
157+
{
158+
side_effect_exprt const see=to_side_effect_expr(querye_in);
159+
if(see.get_statement()==ID_nondet)
160+
{
161+
// TODO(marek-trtik): Add computation of a proper points-to set for NONDET
162+
// in a side-effect expression
163+
assert(false);
164+
}
165+
}
166+
175167
const exprt* querye=&querye_in;
176168
while(querye->id()==ID_typecast)
177169
querye=&querye->op0();
@@ -207,7 +199,7 @@ static void collect_lvsa_access_paths(
207199
else if(get_underlying_object(transformed_object).id()=="NULL-object")
208200
continue;
209201

210-
result.insert(taint_object_numbering.number(transformed_object));
202+
result.insert(transformed_object);
211203
}
212204
}
213205
else
@@ -216,13 +208,55 @@ static void collect_lvsa_access_paths(
216208
collect_lvsa_access_paths(
217209
*it,
218210
ns,
219-
result,
220211
lvsa,
221212
instit,
222-
taint_object_numbering);
213+
result);
223214
}
224215
}
225216

217+
static void collect_lvsa_access_paths(
218+
exprt const& querye_in,
219+
namespacet const& ns,
220+
local_value_set_analysist& lvsa,
221+
instruction_iteratort const& instit,
222+
object_numberingt& taint_object_numbering,
223+
lvalue_numbers_sett& result,
224+
bool &singular)
225+
{
226+
std::set<exprt> referees;
227+
collect_lvsa_access_paths(
228+
querye_in,
229+
ns,
230+
lvsa,
231+
instit,
232+
referees);
233+
234+
singular=lvsa.is_singular(referees);
235+
236+
for(const exprt &object : referees)
237+
result.insert(taint_object_numbering.number(object));
238+
}
239+
240+
static void collect_lvsa_access_paths(
241+
exprt const& querye_in,
242+
namespacet const& ns,
243+
lvalue_numbers_sett &result,
244+
local_value_set_analysist& lvsa,
245+
instruction_iteratort const& instit,
246+
object_numberingt& taint_object_numbering)
247+
{
248+
bool singular=false;
249+
250+
collect_lvsa_access_paths(
251+
querye_in,
252+
ns,
253+
lvsa,
254+
instit,
255+
taint_object_numbering,
256+
result,
257+
singular);
258+
}
259+
226260
static void populate_formals_to_actuals(
227261
local_value_set_analysist& lvsa,
228262
const irep_idt& fname,
@@ -817,49 +851,29 @@ void taint_algorithm_computing_summary_of_functiont::handle_assignment(
817851
}
818852

819853
lvalue_numbers_sett lhs;
854+
bool singular=false;
820855
collect_lvsa_access_paths(
821856
asgn.lhs(),
822857
program->get_namespace(),
823-
lhs,
824858
lvsa,
825859
Iit,
826-
*numbering);
827-
for(const auto &path : lhs)
860+
*numbering,
861+
lhs,
862+
singular);
863+
864+
if(singular)
828865
{
829-
// Get whether an expression refers to a unique dynamic lvalue, as
830-
// opposed to e.g. a dynamic object expression, which refers to the
831-
// general case of objects allocated [at a particular program point]
832-
bool is_singular_object = is_expr_singular_object(*numbering, path);
833-
if(lhs.size()>1 || (lhs.size()==1 && !is_singular_object))
834-
maybe_assign(result, path, taint);
835-
else
836-
assign(result, path, taint);
866+
// Singular implies that lhs has exactly one element,
867+
// so we can access it directly
868+
assign(result, *lhs.begin(), taint);
837869
}
838-
}
839-
840-
void taint_algorithm_computing_summary_of_functiont::
841-
compute_aliased_numbers_of_lvalue(
842-
const taint_lvaluet &lvalue,
843-
const instruction_iteratort &Iit,
844-
local_value_set_analysist &lvsa,
845-
lvalue_numbers_sett &numbers_of_aliases)
846-
{
847-
if(lvalue.id() == ID_side_effect)
870+
else
848871
{
849-
side_effect_exprt const see=to_side_effect_expr(lvalue);
850-
if(see.get_statement()==ID_nondet)
872+
for(const auto &path : lhs)
851873
{
852-
// TODO!
853-
assert(false);
874+
maybe_assign(result, path, taint);
854875
}
855876
}
856-
collect_lvsa_access_paths(
857-
lvalue,
858-
program->get_namespace(),
859-
numbers_of_aliases,
860-
lvsa,
861-
Iit,
862-
*numbering);
863877
}
864878

865879
taint_sett taint_algorithm_computing_summary_of_functiont::
@@ -870,11 +884,13 @@ taint_sett taint_algorithm_computing_summary_of_functiont::
870884
const numbered_lvalue_to_taint_mapt &a)
871885
{
872886
lvalue_numbers_sett numbers_of_aliases;
873-
compute_aliased_numbers_of_lvalue(
887+
collect_lvsa_access_paths(
874888
lvalue,
875-
Iit,
889+
program->get_namespace(),
890+
numbers_of_aliases,
876891
lvsa,
877-
numbers_of_aliases);
892+
Iit,
893+
*numbering);
878894
taint_sett result;
879895
for(taint_lvalue_numbert lvalue_number : numbers_of_aliases)
880896
{
@@ -895,19 +911,28 @@ void taint_algorithm_computing_summary_of_functiont::
895911
numbered_lvalue_to_taint_mapt &result)
896912
{
897913
lvalue_numbers_sett numbers_of_aliases;
898-
compute_aliased_numbers_of_lvalue(
914+
bool singular=false;
915+
collect_lvsa_access_paths(
899916
lvalue,
900-
Iit,
917+
program->get_namespace(),
901918
lvsa,
902-
numbers_of_aliases);
903-
for(taint_lvalue_numbert lvalue_number : numbers_of_aliases)
919+
Iit,
920+
*numbering,
921+
numbers_of_aliases,
922+
singular);
923+
924+
if(singular && is_allowed_pure_assignment)
925+
{
926+
// Singular implies that lhs has exactly one element,
927+
// so we can access it directly
928+
assign(result, *numbers_of_aliases.begin(), taint_from_rule);
929+
}
930+
else
904931
{
905-
bool is_singular_object = is_expr_singular_object(*numbering, lvalue_number);
906-
if(!is_allowed_pure_assignment || numbers_of_aliases.size()>1ULL ||
907-
(numbers_of_aliases.size()==1ULL && !is_singular_object))
932+
for(taint_lvalue_numbert lvalue_number : numbers_of_aliases)
933+
{
908934
maybe_assign(result, lvalue_number, taint_from_rule);
909-
else
910-
assign(result, lvalue_number, taint_from_rule);
935+
}
911936
}
912937
}
913938

@@ -944,11 +969,13 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
944969
replace_it->second, Iit, lvsa, a);
945970

946971
lvalue_numbers_sett numbers_of_aliases;
947-
compute_aliased_numbers_of_lvalue(
972+
collect_lvsa_access_paths(
948973
replace_it->second,
949-
Iit,
974+
program->get_namespace(),
975+
numbers_of_aliases,
950976
lvsa,
951-
numbers_of_aliases);
977+
Iit,
978+
*numbering);
952979
assert(!numbers_of_aliases.empty());
953980
std::stringstream sstr;
954981
sstr << "However, instead of applying NONDET as the right-hand-side"

src/taint-analysis/taint_summary.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,6 @@ class taint_algorithm_computing_summary_of_functiont
266266
instruction_iteratort const& Iit,
267267
local_value_set_analysist &lvsa);
268268

269-
void compute_aliased_numbers_of_lvalue(
270-
const taint_lvaluet &lvalue,
271-
const instruction_iteratort &Iit,
272-
local_value_set_analysist &lvsa,
273-
lvalue_numbers_sett &numbers_of_aliases);
274-
275269
taint_sett compute_taint_of_aliased_numbers_of_lvalue(
276270
const taint_lvaluet &lvalue,
277271
const instruction_iteratort &Iit,

0 commit comments

Comments
 (0)