Skip to content

Commit e8015b8

Browse files
committed
Add unit test to check value-set behaviour in the presence of constants
This ensures that in a simple case with constant and non-constant pointers to the same target, the value-set domain appears to behave the same way for both, but in fact optimises by avoiding storing the constant pointer.
1 parent ca2a7b3 commit e8015b8

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

unit/pointer-analysis/value_set.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,91 @@ SCENARIO(
311311
}
312312
}
313313
}
314+
315+
GIVEN("A base value-set")
316+
{
317+
value_sett base_value_set;
318+
319+
// Create int i; int *ptr;
320+
321+
signedbv_typet int32_type(32);
322+
323+
symbolt i;
324+
i.name = "i";
325+
i.base_name = "i";
326+
i.pretty_name = "i";
327+
i.type = int32_type;
328+
i.is_static_lifetime = true;
329+
symbol_table.add(i);
330+
331+
symbolt ptr;
332+
ptr.name = "ptr";
333+
ptr.base_name = "ptr";
334+
ptr.pretty_name = "ptr";
335+
ptr.type = pointer_typet(int32_type, 64);
336+
ptr.is_static_lifetime = true;
337+
symbol_table.add(ptr);
338+
339+
// Assign ptr = &i (in the base value-set):
340+
341+
code_assignt assign_ptr(
342+
ptr.symbol_expr(), address_of_exprt(i.symbol_expr()));
343+
base_value_set.apply_code(assign_ptr, ns);
344+
345+
value_set.set_base_value_set(&base_value_set);
346+
347+
WHEN("Querying ptr via the base value-set")
348+
{
349+
value_setst::valuest result;
350+
base_value_set.get_value_set(ptr.symbol_expr(), result, ns);
351+
352+
THEN("The answer should be { &i }")
353+
{
354+
REQUIRE(result.size() == 1);
355+
REQUIRE(object_descriptor_matches(*result.begin(), i.symbol_expr()));
356+
}
357+
358+
WHEN("Querying ptr via the child value-set")
359+
{
360+
value_setst::valuest child_result;
361+
value_set.get_value_set(ptr.symbol_expr(), child_result, ns);
362+
363+
THEN("The answer should also be { &i }")
364+
{
365+
REQUIRE(result == child_result);
366+
}
367+
}
368+
369+
WHEN("ptr is weakly updated in the child value-set")
370+
{
371+
null_pointer_exprt null_pointer(to_pointer_type(ptr.type));
372+
373+
// Final 'true' parameter makes this a weak write:
374+
value_set.assign(ptr.symbol_expr(), null_pointer, ns, false, true);
375+
376+
WHEN("ptr is queried again")
377+
{
378+
value_setst::valuest requery_result;
379+
value_set.get_value_set(ptr.symbol_expr(), requery_result, ns);
380+
381+
THEN("The answer should be { null, &i }")
382+
{
383+
REQUIRE(requery_result.size() == 2);
384+
385+
bool found_i = false, found_null = false;
386+
for(const exprt &result : requery_result)
387+
{
388+
if(object_descriptor_matches(result, i.symbol_expr()))
389+
found_i = true;
390+
else if(object_descriptor_matches(result, null_pointer))
391+
found_null = true;
392+
}
393+
394+
REQUIRE(found_i);
395+
REQUIRE(found_null);
396+
}
397+
}
398+
}
399+
}
400+
}
314401
}

0 commit comments

Comments
 (0)