Skip to content

Commit ea472cb

Browse files
committed
Make has_symbol configurable and deprecate the existing has_symbol
The existing code did not permit configuring what kinds of symbols are to be found. It had a single user within the code base, and even that one was not a good use of it for it constructed a single-element set. The new implementation does not yet make use of potential efficiency advantages of "has a symbol" over "find the existing symbols," but such improvements will be done based on further cleanup of find_symbols code.
1 parent b22ded7 commit ea472cb

File tree

5 files changed

+52
-19
lines changed

5 files changed

+52
-19
lines changed

src/ansi-c/goto_check_c.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,12 +461,12 @@ void goto_check_ct::invalidate(const exprt &lhs)
461461
else if(lhs.id() == ID_symbol)
462462
{
463463
// clear all assertions about 'symbol'
464-
find_symbols_sett find_symbols_set{to_symbol_expr(lhs).get_identifier()};
464+
const irep_idt &lhs_id = to_symbol_expr(lhs).get_identifier();
465465

466466
for(auto it = assertions.begin(); it != assertions.end();)
467467
{
468468
if(
469-
has_symbol(it->second, find_symbols_set) ||
469+
has_symbol(it->second, lhs_id, kindt::F_EXPR) ||
470470
has_subexpr(it->second, ID_dereference))
471471
{
472472
it = assertions.erase(it);

src/goto-symex/postcondition.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,16 @@ bool postconditiont::is_used(
164164
else if(expr.id()==ID_dereference)
165165
{
166166
// aliasing may happen here
167-
const std::vector<exprt> expr_set =
168-
value_set.get_value_set(to_dereference_expr(expr).pointer(), ns);
169-
const auto original_names = make_range(expr_set).map(
170-
[](const exprt &e) { return get_original_name(e); });
171-
const std::unordered_set<irep_idt> symbols =
172-
find_symbols_or_nexts(original_names.begin(), original_names.end());
173-
return symbols.find(identifier)!=symbols.end();
167+
for(const exprt &e :
168+
value_set.get_value_set(to_dereference_expr(expr).pointer(), ns))
169+
{
170+
if(has_symbol(get_original_name(e), identifier, kindt::F_BOTH))
171+
{
172+
return true;
173+
}
174+
}
175+
176+
return false;
174177
}
175178
else
176179
forall_operands(it, expr)

src/goto-symex/precondition.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,19 @@ void preconditiont::compute_rec(exprt &dest)
113113

114114
// aliasing may happen here
115115

116-
const std::vector<exprt> expr_set = value_sets.get_values(
117-
SSA_step.source.function_id, target, deref_expr.pointer());
118-
const std::unordered_set<irep_idt> symbols =
119-
find_symbols_or_nexts(expr_set.begin(), expr_set.end());
116+
bool may_alias = false;
117+
for(const exprt &e : value_sets.get_values(
118+
SSA_step.source.function_id, target, deref_expr.pointer()))
119+
{
120+
if(has_symbol(e, lhs_identifier, kindt::F_BOTH))
121+
{
122+
may_alias = true;
123+
break;
124+
}
125+
}
120126

121-
if(symbols.find(lhs_identifier)!=symbols.end())
127+
if(may_alias)
122128
{
123-
// may alias!
124129
exprt tmp;
125130
tmp.swap(deref_expr.pointer());
126131
dereference(SSA_step.source.function_id, target, tmp, ns, value_sets);

src/util/find_symbols.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ Author: Daniel Kroening, [email protected]
1313
#include "range.h"
1414
#include "std_expr.h"
1515

16-
enum class kindt { F_TYPE, F_TYPE_NON_PTR, F_EXPR, F_BOTH };
17-
1816
void find_symbols_or_nexts(const exprt &src, find_symbols_sett &dest)
1917
{
2018
find_symbols(src, dest, true, true);
@@ -173,6 +171,13 @@ void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest)
173171
}
174172
}
175173

174+
bool has_symbol(const exprt &src, const irep_idt &identifier, kindt kind)
175+
{
176+
find_symbols_sett tmp_dest;
177+
find_symbols(kind, src, tmp_dest);
178+
return tmp_dest.find(identifier) != tmp_dest.end();
179+
}
180+
176181
void find_type_symbols(const exprt &src, find_symbols_sett &dest)
177182
{
178183
find_symbols(kindt::F_TYPE, src, dest);

src/util/find_symbols.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,37 @@ Author: Daniel Kroening, [email protected]
1010
#ifndef CPROVER_UTIL_FIND_SYMBOLS_H
1111
#define CPROVER_UTIL_FIND_SYMBOLS_H
1212

13+
#include "deprecate.h"
14+
#include "irep.h"
15+
1316
#include <algorithm>
1417
#include <set>
1518
#include <unordered_set>
1619

17-
#include "irep.h"
18-
1920
class exprt;
2021
class symbol_exprt;
2122
class typet;
2223

2324
typedef std::unordered_set<irep_idt> find_symbols_sett;
2425

26+
/// Kinds of symbols to be considered by \ref has_symbol or \ref find_symbols.
27+
enum class kindt
28+
{
29+
/// Struct, union, or enum tag symbols.
30+
F_TYPE,
31+
/// Struct, union, or enum tag symbols when the expression using them is not a
32+
/// pointer.
33+
F_TYPE_NON_PTR,
34+
/// Symbol expressions.
35+
F_EXPR,
36+
/// Current or next-state symbol expressions.
37+
F_BOTH,
38+
};
39+
40+
/// Returns true if one of the symbols in \p src with identifier \p identifier
41+
/// is of kind \p kind.
42+
bool has_symbol(const exprt &src, const irep_idt &identifier, kindt kind);
43+
2544
/// Add to the set \p dest the sub-expressions of \p src with id ID_symbol or
2645
/// ID_next_symbol
2746
void find_symbols_or_nexts(const exprt &src, find_symbols_sett &dest);
@@ -59,6 +78,7 @@ std::set<symbol_exprt> find_symbols(const exprt &src);
5978
/// Find identifiers of the sub expressions with id ID_symbol
6079
std::unordered_set<irep_idt> find_symbol_identifiers(const exprt &src);
6180

81+
DEPRECATED(SINCE(2022, 3, 14, "use has_symbol(exprt, irep_idt, symbol_kindt)"))
6282
/// \return true if one of the symbols in \p src is present in \p symbols
6383
bool has_symbol(
6484
const exprt &src,

0 commit comments

Comments
 (0)