Skip to content

Commit b03ec16

Browse files
authored
Merge pull request diffblue#239 from diffblue/bugfix/value_sets_fi_and_reaching_defs_retrievals_of_dynamic_objects
SEC-41 : Bugfix: value_sets and reaching_defs retrievals of dynamic objects
2 parents 739c7f5 + db79106 commit b03ec16

File tree

6 files changed

+74
-11
lines changed

6 files changed

+74
-11
lines changed
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <assert.h>
2+
#include <malloc.h>
3+
4+
struct rrr
5+
{
6+
char j;
7+
int y;
8+
};
9+
10+
void foo(struct rrr *r)
11+
{
12+
r->j = 1;
13+
}
14+
15+
int main(int argc, char* argv[])
16+
{
17+
struct rrr* r=malloc(sizeof(struct rrr));
18+
foo(r);
19+
if (r->j==1)
20+
{
21+
assert(1);
22+
return 0;
23+
}
24+
return -1;
25+
}
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--full-slice --add-library
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$

src/analyses/goto_rw.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,22 @@ void rw_range_set_value_sett::get_objects_dereference(
613613
new_size=std::min(size, new_size);
614614
}
615615

616+
// We must ensure that the artificial reference (introduced in
617+
// 'value_set_dereferencet::build_reference_to') to a dynamic object
618+
// obtained by dereferencing the pointer in 'deref' gets to the resulting
619+
// points-to-set. The following condition check whether the obtained
620+
// object is the artificial reference.
621+
if(object.is_not_nil() && object.id()==ID_symbol &&
622+
as_string(to_symbol_expr(object).get_identifier()).find(
623+
get_vsderef_dynamic_object_prefix())==0UL)
624+
{
625+
add(
626+
mode,
627+
to_symbol_expr(object).get_identifier(),
628+
range_start,
629+
range_start+new_size);
630+
}
631+
616632
// value_set_dereferencet::build_reference_to will turn *p into
617633
// DYNAMIC_OBJECT(p) ? *p : invalid_objectN
618634
if(object.is_not_nil() &&

src/analyses/reaching_definitions.cpp

+15-10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Date: February 2013
2222
#include <util/make_unique.h>
2323

2424
#include <pointer-analysis/value_set_analysis_fi.h>
25+
#include <pointer-analysis/value_set_dereference.h>
2526

2627
#include "is_threaded.h"
2728
#include "dirty.h"
@@ -309,21 +310,25 @@ void rd_range_domaint::transform_assign(
309310
forall_rw_range_set_w_objects(it, rw_set)
310311
{
311312
const irep_idt &identifier=it->first;
312-
// ignore symex::invalid_object
313+
bool do_kill=is_must_alias;
313314
const symbolt *symbol_ptr;
314315
if(ns.lookup(identifier, symbol_ptr))
315-
continue;
316-
INVARIANT_STRUCTURED(
317-
symbol_ptr!=nullptr,
318-
nullptr_exceptiont,
319-
"Symbol is in symbol table");
316+
{
317+
if(as_string(identifier).find(get_vsderef_dynamic_object_prefix())!=0UL)
318+
// ignore symex::invalid_object
319+
continue;
320+
}
321+
else
322+
{
323+
do_kill=do_kill &&
324+
(!rd.get_is_threaded()(from) ||
325+
(!symbol_ptr->is_shared() &&
326+
!rd.get_is_dirty()(identifier)));
327+
}
320328

321329
const range_domaint &ranges=rw_set.get_ranges(it);
322330

323-
if(is_must_alias &&
324-
(!rd.get_is_threaded()(from) ||
325-
(!symbol_ptr->is_shared() &&
326-
!rd.get_is_dirty()(identifier))))
331+
if(do_kill)
327332
for(const auto &range : ranges)
328333
kill(identifier, range.first, range.second);
329334

src/pointer-analysis/value_set_dereference.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ const exprt &value_set_dereferencet::get_symbol(const exprt &expr)
6060
return expr;
6161
}
6262

63+
const std::string &get_vsderef_dynamic_object_prefix()
64+
{
65+
static std::string prefix(CPROVER_PREFIX "_VSDEREF_");
66+
return prefix;
67+
}
68+
6369
/// \par parameters: expression dest, to be dereferenced under given guard,
6470
/// and given mode
6571
/// \return returns pointer after dereferencing
@@ -344,7 +350,9 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
344350
result.pointer_guard=dynamic_object_expr;
345351

346352
// can't remove here, turn into *p
347-
result.value=dereference_exprt(pointer_expr, dereference_type);
353+
result.value=symbol_exprt(
354+
get_vsderef_dynamic_object_prefix()+from_expr(root_object),
355+
ns.follow(dereference_type));
348356

349357
if(options.get_bool_option("pointer-check"))
350358
{

src/pointer-analysis/value_set_dereference.h

+2
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,6 @@ class value_set_dereferencet
144144
const exprt &offset);
145145
};
146146

147+
const std::string &get_vsderef_dynamic_object_prefix();
148+
147149
#endif // CPROVER_POINTER_ANALYSIS_VALUE_SET_DEREFERENCE_H

0 commit comments

Comments
 (0)