Skip to content

Commit 05e04bd

Browse files
romainbrenguiersmowton
authored andcommitted
Make field sensitivity max array size configurable
This will allow the user of symex to set this limit as needed instead of fixing it to an arbitrary value.
1 parent 869f2cd commit 05e04bd

14 files changed

+43
-18
lines changed

src/goto-instrument/accelerate/scratch_program.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ bool scratch_programt::check_sat(bool do_slice, guard_managert &guard_manager)
3838

3939
symex_state = util_make_unique<goto_symex_statet>(
4040
symex_targett::sourcet(goto_functionst::entry_point(), *this),
41+
DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE,
4142
guard_manager,
4243
[this](const irep_idt &id) {
4344
return path_storage.get_unique_l2_index(id);

src/goto-symex/field_sensitivity.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ exprt field_sensitivityt::apply(
114114
if(
115115
l2_size.id() == ID_constant &&
116116
numeric_cast_v<mp_integer>(to_constant_expr(l2_size)) <=
117-
MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
117+
max_field_sensitivity_array_size)
118118
{
119119
if(l2_index.get().id() == ID_constant)
120120
{
@@ -183,7 +183,7 @@ exprt field_sensitivityt::get_fields(
183183
to_array_type(ssa_expr.type()).size().id() == ID_constant &&
184184
numeric_cast_v<mp_integer>(
185185
to_constant_expr(to_array_type(ssa_expr.type()).size())) <=
186-
MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
186+
max_field_sensitivity_array_size)
187187
{
188188
const array_typet &type = to_array_type(ssa_expr.type());
189189
const std::size_t array_size =
@@ -305,7 +305,7 @@ void field_sensitivityt::field_assignments_rec(
305305
numeric_cast_v<std::size_t>(to_constant_expr(type->size()));
306306
PRECONDITION(lhs_fs.operands().size() == array_size);
307307

308-
if(array_size > MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
308+
if(array_size > max_field_sensitivity_array_size)
309309
return;
310310

311311
exprt::operandst::const_iterator fs_it = lhs_fs.operands().begin();
@@ -339,7 +339,7 @@ void field_sensitivityt::field_assignments_rec(
339339
}
340340
}
341341

342-
bool field_sensitivityt::is_divisible(const ssa_exprt &expr)
342+
bool field_sensitivityt::is_divisible(const ssa_exprt &expr) const
343343
{
344344
if(expr.type().id() == ID_struct || expr.type().id() == ID_struct_tag)
345345
return true;
@@ -349,7 +349,7 @@ bool field_sensitivityt::is_divisible(const ssa_exprt &expr)
349349
expr.type().id() == ID_array &&
350350
to_array_type(expr.type()).size().id() == ID_constant &&
351351
numeric_cast_v<mp_integer>(to_constant_expr(
352-
to_array_type(expr.type()).size())) <= MAX_FIELD_SENSITIVITY_ARRAY_SIZE)
352+
to_array_type(expr.type()).size())) <= max_field_sensitivity_array_size)
353353
{
354354
return true;
355355
}

src/goto-symex/field_sensitivity.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class symex_targett;
6262
/// When `index` is not a constant, `array[index]` is replaced by
6363
/// `{array[[0]]; array[[1]]; …index]`.
6464
/// Note that this process does not apply to arrays whose size is not constant,
65-
/// and arrays whose size exceed the bound \ref MAX_FIELD_SENSITIVITY_ARRAY_SIZE
65+
/// and arrays whose size exceed the bound \c max_field_sensitivity_array_size.
6666
/// See \ref field_sensitivityt::apply.
6767
///
6868
/// ### Symbols representing arrays
@@ -80,6 +80,13 @@ class symex_targett;
8080
class field_sensitivityt
8181
{
8282
public:
83+
/// \param max_array_size: maximum size for which field sensitivity will be
84+
/// applied to array cells
85+
explicit field_sensitivityt(std::size_t max_array_size)
86+
: max_field_sensitivity_array_size(max_array_size)
87+
{
88+
}
89+
8390
/// Assign to the individual fields of a non-expanded symbol \p lhs. This is
8491
/// required whenever prior steps have updated the full object rather than
8592
/// individual fields, e.g., in case of assignments to an array at an unknown
@@ -133,12 +140,14 @@ class field_sensitivityt
133140
/// \param expr: the expression to evaluate
134141
/// \return False, if and only if, \p expr would be a single field-sensitive
135142
/// SSA expression.
136-
static bool is_divisible(const ssa_exprt &expr);
143+
bool is_divisible(const ssa_exprt &expr) const;
137144

138145
private:
139146
/// whether or not to invoke \ref field_sensitivityt::apply
140147
bool run_apply = true;
141148

149+
const std::size_t max_field_sensitivity_array_size;
150+
142151
void field_assignments_rec(
143152
const namespacet &ns,
144153
goto_symex_statet &state,

src/goto-symex/goto_symex.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ struct symex_configt final
7070
/// includes diagnostic information about call stack and guard size.
7171
bool show_symex_steps;
7272

73+
/// Maximum sizes for which field sensitivity will be applied to array cells
74+
std::size_t max_field_sensitivity_array_size;
75+
7376
/// \brief Construct a symex_configt using options specified in an
7477
/// \ref optionst
7578
explicit symex_configt(const optionst &options);

src/goto-symex/goto_symex_state.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ static void get_l1_name(exprt &expr);
3434

3535
goto_symex_statet::goto_symex_statet(
3636
const symex_targett::sourcet &_source,
37+
std::size_t max_field_sensitive_array_size,
3738
guard_managert &manager,
3839
std::function<std::size_t(const irep_idt &)> fresh_l2_name_provider)
3940
: goto_statet(manager),
4041
source(_source),
4142
guard_manager(manager),
4243
symex_target(nullptr),
44+
field_sensitivity(max_field_sensitive_array_size),
4345
record_events({true}),
4446
fresh_l2_name_provider(fresh_l2_name_provider)
4547
{
@@ -370,7 +372,7 @@ bool goto_symex_statet::l2_thread_read_encoding(
370372
}
371373

372374
// only continue if an indivisible object is being accessed
373-
if(field_sensitivityt::is_divisible(expr))
375+
if(field_sensitivity.is_divisible(expr))
374376
return false;
375377

376378
const ssa_exprt ssa_l1 = remove_level_2(expr);
@@ -498,7 +500,7 @@ goto_symex_statet::write_is_shared_resultt goto_symex_statet::write_is_shared(
498500
}
499501

500502
// only continue if an indivisible object is being accessed
501-
if(field_sensitivityt::is_divisible(expr))
503+
if(field_sensitivity.is_divisible(expr))
502504
return write_is_shared_resultt::NOT_SHARED;
503505

504506
if(atomic_section_id != 0)

src/goto-symex/goto_symex_state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class goto_symex_statet final : public goto_statet
4747
public:
4848
goto_symex_statet(
4949
const symex_targett::sourcet &,
50+
std::size_t max_field_sensitive_array_size,
5051
guard_managert &manager,
5152
std::function<std::size_t(const irep_idt &)> fresh_l2_name_provider);
5253
~goto_symex_statet();

src/goto-symex/symex_assign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ void symex_assignt::assign_non_struct_symbol(
204204
current_assignment_type);
205205

206206
const ssa_exprt &l1_lhs = assignment.lhs;
207-
if(field_sensitivityt::is_divisible(l1_lhs))
207+
if(state.field_sensitivity.is_divisible(l1_lhs))
208208
{
209209
// Split composite symbol lhs into its components
210210
state.field_sensitivity.field_assignments(

src/goto-symex/symex_builtin_functions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ void goto_symext::symex_printf(
394394
else
395395
{
396396
clean_expr(*va_args, state, false);
397-
*va_args = field_sensitivityt{}.apply(ns, state, *va_args, false);
397+
*va_args = state.field_sensitivity.apply(ns, state, *va_args, false);
398398
*va_args = state.rename(*va_args, ns).get();
399399
if(va_args->id() != ID_array)
400400
{

src/goto-symex/symex_goto.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ static void merge_names(
618618
}
619619

620620
// field sensitivity: only merge on individual fields
621-
if(field_sensitivityt::is_divisible(ssa))
621+
if(dest_state.field_sensitivity.is_divisible(ssa))
622622
return;
623623

624624
// shared variables are renamed on every access anyway, we don't need to

src/goto-symex/symex_main.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ symex_configt::symex_configt(const optionst &options)
4444
partial_loops(options.get_bool_option("partial-loops")),
4545
debug_level(unsafe_string2int(options.get_option("debug-level"))),
4646
run_validation_checks(options.get_bool_option("validate-ssa-equation")),
47-
show_symex_steps(options.get_bool_option("show-goto-symex-steps"))
47+
show_symex_steps(options.get_bool_option("show-goto-symex-steps")),
48+
max_field_sensitivity_array_size(
49+
options.get_unsigned_int_option("max-field-sensitivity-array-size"))
4850
{
4951
}
5052

@@ -347,6 +349,7 @@ std::unique_ptr<goto_symext::statet> goto_symext::initialize_entry_point_state(
347349
// create and prepare the state
348350
auto state = util_make_unique<statet>(
349351
symex_targett::sourcet(entry_point_id, start_function->body),
352+
symex_config.max_field_sensitivity_array_size,
350353
guard_manager,
351354
[storage](const irep_idt &id) { return storage->get_unique_l2_index(id); });
352355

src/util/magic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ constexpr std::size_t DSTRING_NUMBERS_MAX = 64;
1818

1919
/// Limit the size of arrays for which field_sensitivity gets applied.
2020
/// Necessary because large constant arrays slow-down the process.
21-
constexpr std::size_t MAX_FIELD_SENSITIVITY_ARRAY_SIZE = 64;
21+
constexpr std::size_t DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE = 64;
2222

2323
#endif

unit/goto-symex/goto_symex_state.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ SCENARIO(
4040
auto fresh_name = [&fresh_name_count](const irep_idt &) {
4141
return fresh_name_count++;
4242
};
43-
goto_symex_statet state{source, manager, fresh_name};
43+
goto_symex_statet state{
44+
source, DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE, manager, fresh_name};
4445

4546
// Initialize dirty field of state
4647
incremental_dirtyt dirty;

unit/goto-symex/symex_assign.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ SCENARIO(
4848
auto fresh_name = [&fresh_name_count](const irep_idt &) {
4949
return fresh_name_count++;
5050
};
51-
goto_symex_statet state{source, manager, fresh_name};
51+
goto_symex_statet state{
52+
source, DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE, manager, fresh_name};
5253

5354
// Initialize dirty field of state
5455
incremental_dirtyt dirty;

unit/goto-symex/try_evaluate_pointer_comparisons.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ SCENARIO(
5555
guard_managert guard_manager;
5656
std::size_t count = 0;
5757
auto fresh_name = [&count](const irep_idt &) { return count++; };
58-
goto_symex_statet state{source, guard_manager, fresh_name};
58+
goto_symex_statet state{source,
59+
DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE,
60+
guard_manager,
61+
fresh_name};
5962

6063
GIVEN("A value set in which pointer symbol `ptr1` only points to `&value1`")
6164
{
@@ -246,7 +249,8 @@ SCENARIO(
246249

247250
// struct_symbol..pointer_field <- &value1
248251
{
249-
field_sensitivityt field_sensitivity;
252+
field_sensitivityt field_sensitivity{
253+
DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE};
250254
const exprt index_fs =
251255
field_sensitivity.apply(ns, state, member_l1.get(), true);
252256
value_set.assign(index_fs, address1_l1.get(), ns, false, false);

0 commit comments

Comments
 (0)