Skip to content

Commit fead2db

Browse files
author
Owen
committed
Factor out value_sett::get_entry_for_symbol
Make this a separate function so it can be used from other places. No change in behaviour.
1 parent 17fa596 commit fead2db

File tree

3 files changed

+87
-36
lines changed

3 files changed

+87
-36
lines changed

src/goto-symex/goto_symex.h

+22
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,28 @@ class goto_symext
315315
virtual void symex_other(statet &state);
316316

317317
void symex_assert(const goto_programt::instructiont &, statet &);
318+
319+
/// Try to filter value sets based on whether possible values of a
320+
/// pointer-typed symbol make the condition true or false. We only do this
321+
/// when there is only one pointer-typed symbol in \p condition.
322+
/// \param state: The current state
323+
/// \param condition: The condition which is being evaluated, which it expects
324+
/// will not have been cleaned or renamed. In practice, it's fine if it has
325+
/// been cleaned and renamed up to level L1.
326+
/// \param value_set_for_true_case: A pointer to the value set that possible
327+
/// values should be removed from if they make the condition false, or
328+
/// nullptr if this shouldn't be done
329+
/// \param value_set_for_false_case: A pointer to the value set that possible
330+
/// values should be removed from if they make the condition true, or
331+
/// nullptr if this shouldn't be done
332+
/// \param ns: A namespace
333+
void try_filter_value_sets(
334+
goto_symex_statet &state,
335+
exprt condition,
336+
value_sett *value_set_for_true_case,
337+
value_sett *value_set_for_false_case,
338+
const namespacet &ns);
339+
318340
virtual void vcc(
319341
const exprt &,
320342
const std::string &msg,

src/pointer-analysis/value_set.cpp

+52-36
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,54 @@ static std::string strip_first_field_from_suffix(
366366
return suffix.substr(field.length() + 1);
367367
}
368368

369+
const value_sett::entryt *value_sett::get_entry_for_symbol(
370+
const irep_idt identifier,
371+
const typet &type,
372+
const std::string &suffix,
373+
const namespacet &ns) const
374+
{
375+
if(
376+
type.id() != ID_pointer && type.id() != ID_signedbv &&
377+
type.id() != ID_unsignedbv && type.id() != ID_array &&
378+
type.id() != ID_struct && type.id() != ID_struct_tag &&
379+
type.id() != ID_union && type.id() != ID_union_tag)
380+
{
381+
return nullptr;
382+
}
383+
384+
const typet &followed_type = type.id() == ID_struct_tag
385+
? ns.follow_tag(to_struct_tag_type(type))
386+
: type.id() == ID_union_tag
387+
? ns.follow_tag(to_union_tag_type(type))
388+
: type;
389+
390+
// look it up
391+
const value_sett::entryt *entry = find_entry(id2string(identifier) + suffix);
392+
393+
// try first component name as suffix if not yet found
394+
if(
395+
!entry &&
396+
(followed_type.id() == ID_struct || followed_type.id() == ID_union))
397+
{
398+
const struct_union_typet &struct_union_type =
399+
to_struct_union_type(followed_type);
400+
401+
const irep_idt &first_component_name =
402+
struct_union_type.components().front().get_name();
403+
404+
entry = find_entry(
405+
id2string(identifier) + "." + id2string(first_component_name) + suffix);
406+
}
407+
408+
if(!entry)
409+
{
410+
// not found? try without suffix
411+
entry = find_entry(identifier);
412+
}
413+
414+
return entry;
415+
}
416+
369417
void value_sett::get_value_set_rec(
370418
const exprt &expr,
371419
object_mapt &dest,
@@ -413,43 +461,11 @@ void value_sett::get_value_set_rec(
413461
}
414462
else if(expr.id()==ID_symbol)
415463
{
416-
irep_idt identifier=to_symbol_expr(expr).get_identifier();
417-
418-
// is it a pointer, integer, array or struct?
419-
if(expr_type.id()==ID_pointer ||
420-
expr_type.id()==ID_signedbv ||
421-
expr_type.id()==ID_unsignedbv ||
422-
expr_type.id()==ID_struct ||
423-
expr_type.id()==ID_union ||
424-
expr_type.id()==ID_array)
425-
{
426-
// look it up
427-
const entryt *entry =
428-
find_entry(id2string(identifier) + suffix);
429-
430-
// try first component name as suffix if not yet found
431-
if(!entry && (expr_type.id() == ID_struct || expr_type.id() == ID_union))
432-
{
433-
const struct_union_typet &struct_union_type=
434-
to_struct_union_type(expr_type);
464+
const entryt *entry = get_entry_for_symbol(
465+
to_symbol_expr(expr).get_identifier(), expr_type, suffix, ns);
435466

436-
const irep_idt &first_component_name =
437-
struct_union_type.components().front().get_name();
438-
439-
entry = find_entry(
440-
id2string(identifier) + "." + id2string(first_component_name) +
441-
suffix);
442-
}
443-
444-
// not found? try without suffix
445-
if(!entry)
446-
entry = find_entry(identifier);
447-
448-
if(entry)
449-
make_union(dest, entry->object_map);
450-
else
451-
insert(dest, exprt(ID_unknown, original_type));
452-
}
467+
if(entry)
468+
make_union(dest, entry->object_map);
453469
else
454470
insert(dest, exprt(ID_unknown, original_type));
455471
}

src/pointer-analysis/value_set.h

+13
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,19 @@ class value_sett
460460
exprt &expr,
461461
const namespacet &ns) const;
462462

463+
/// Get the entry for the symbol and suffix
464+
/// \param identifier: The identifier for the symbol
465+
/// \param type: The type of the symbol
466+
/// \param suffix: The suffix for the entry
467+
/// \param ns: The global namespace, for following \p type if it is a
468+
/// struct tag type or a union tag type
469+
/// \return The entry for the symbol and suffix
470+
const value_sett::entryt *get_entry_for_symbol(
471+
const irep_idt identifier,
472+
const typet &type,
473+
const std::string &suffix,
474+
const namespacet &ns) const;
475+
463476
protected:
464477
/// Reads the set of objects pointed to by `expr`, including making
465478
/// recursive lookups for dereference operations etc.

0 commit comments

Comments
 (0)