Skip to content

Commit 41d2563

Browse files
Merge pull request diffblue#101 from diffblue/mariusmc92/cleanup/move-singularity-in-lvsa
Added LVSA method for singularity check
2 parents 01c8c31 + b497aec commit 41d2563

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

+33
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

+2
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

+97-70
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

-6
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)