@@ -49,31 +49,13 @@ static bool is_pure_local(const exprt &lvalue, const symbol_utilst &nsu)
49
49
!nsu.is_static (lvalue);
50
50
}
51
51
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
-
62
52
// //////////////////////////////////////////////////////////////////////////////
63
53
// /
64
54
// / LVSA related stuff : Should be moved to LVSA!
65
55
// /
66
56
// //////////////////////////////////////////////////////////////////////////////
67
57
68
58
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
-
77
59
struct parameter_matches_id {
78
60
parameter_matches_id (const irep_idt& _id) : id(_id) {}
79
61
bool operator ()(const code_typet::parametert& p) const
@@ -167,11 +149,21 @@ static exprt transform_external_objects(const exprt& e)
167
149
static void collect_lvsa_access_paths (
168
150
exprt const & querye_in,
169
151
namespacet const & ns,
170
- lvalue_numbers_sett& result,
171
152
local_value_set_analysist& lvsa,
172
153
instruction_iteratort const & instit,
173
- object_numberingt& taint_object_numbering )
154
+ std::set<exprt> &result )
174
155
{
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
+
175
167
const exprt* querye=&querye_in;
176
168
while (querye->id ()==ID_typecast)
177
169
querye=&querye->op0 ();
@@ -207,7 +199,7 @@ static void collect_lvsa_access_paths(
207
199
else if (get_underlying_object (transformed_object).id ()==" NULL-object" )
208
200
continue ;
209
201
210
- result.insert (taint_object_numbering. number ( transformed_object) );
202
+ result.insert (transformed_object);
211
203
}
212
204
}
213
205
else
@@ -216,13 +208,55 @@ static void collect_lvsa_access_paths(
216
208
collect_lvsa_access_paths (
217
209
*it,
218
210
ns,
219
- result,
220
211
lvsa,
221
212
instit,
222
- taint_object_numbering );
213
+ result );
223
214
}
224
215
}
225
216
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
+
226
260
static void populate_formals_to_actuals (
227
261
local_value_set_analysist& lvsa,
228
262
const irep_idt& fname,
@@ -817,49 +851,29 @@ void taint_algorithm_computing_summary_of_functiont::handle_assignment(
817
851
}
818
852
819
853
lvalue_numbers_sett lhs;
854
+ bool singular=false ;
820
855
collect_lvsa_access_paths (
821
856
asgn.lhs (),
822
857
program->get_namespace (),
823
- lhs,
824
858
lvsa,
825
859
Iit,
826
- *numbering);
827
- for (const auto &path : lhs)
860
+ *numbering,
861
+ lhs,
862
+ singular);
863
+
864
+ if (singular)
828
865
{
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);
837
869
}
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
848
871
{
849
- side_effect_exprt const see=to_side_effect_expr (lvalue);
850
- if (see.get_statement ()==ID_nondet)
872
+ for (const auto &path : lhs)
851
873
{
852
- // TODO!
853
- assert (false );
874
+ maybe_assign (result, path, taint);
854
875
}
855
876
}
856
- collect_lvsa_access_paths (
857
- lvalue,
858
- program->get_namespace (),
859
- numbers_of_aliases,
860
- lvsa,
861
- Iit,
862
- *numbering);
863
877
}
864
878
865
879
taint_sett taint_algorithm_computing_summary_of_functiont::
@@ -870,11 +884,13 @@ taint_sett taint_algorithm_computing_summary_of_functiont::
870
884
const numbered_lvalue_to_taint_mapt &a)
871
885
{
872
886
lvalue_numbers_sett numbers_of_aliases;
873
- compute_aliased_numbers_of_lvalue (
887
+ collect_lvsa_access_paths (
874
888
lvalue,
875
- Iit,
889
+ program->get_namespace (),
890
+ numbers_of_aliases,
876
891
lvsa,
877
- numbers_of_aliases);
892
+ Iit,
893
+ *numbering);
878
894
taint_sett result;
879
895
for (taint_lvalue_numbert lvalue_number : numbers_of_aliases)
880
896
{
@@ -895,19 +911,28 @@ void taint_algorithm_computing_summary_of_functiont::
895
911
numbered_lvalue_to_taint_mapt &result)
896
912
{
897
913
lvalue_numbers_sett numbers_of_aliases;
898
- compute_aliased_numbers_of_lvalue (
914
+ bool singular=false ;
915
+ collect_lvsa_access_paths (
899
916
lvalue,
900
- Iit ,
917
+ program-> get_namespace () ,
901
918
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
904
931
{
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
+ {
908
934
maybe_assign (result, lvalue_number, taint_from_rule);
909
- else
910
- assign (result, lvalue_number, taint_from_rule);
935
+ }
911
936
}
912
937
}
913
938
@@ -944,11 +969,13 @@ numbered_lvalue_to_taint_mapt taint_algorithm_computing_summary_of_functiont::
944
969
replace_it->second , Iit, lvsa, a);
945
970
946
971
lvalue_numbers_sett numbers_of_aliases;
947
- compute_aliased_numbers_of_lvalue (
972
+ collect_lvsa_access_paths (
948
973
replace_it->second ,
949
- Iit,
974
+ program->get_namespace (),
975
+ numbers_of_aliases,
950
976
lvsa,
951
- numbers_of_aliases);
977
+ Iit,
978
+ *numbering);
952
979
assert (!numbers_of_aliases.empty ());
953
980
std::stringstream sstr;
954
981
sstr << " However, instead of applying NONDET as the right-hand-side"
0 commit comments