Skip to content

Commit 85d15ee

Browse files
committed
Refactor out havoc utility functions
1 parent 3092e7b commit 85d15ee

File tree

9 files changed

+141
-84
lines changed

9 files changed

+141
-84
lines changed

src/goto-instrument/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ SRC = accelerate/accelerate.cpp \
4343
goto_instrument_parse_options.cpp \
4444
goto_program2code.cpp \
4545
havoc_loops.cpp \
46+
havoc_utils.cpp \
4647
horn_encoding.cpp \
4748
insert_final_assert_false.cpp \
4849
interrupt.cpp \

src/goto-instrument/contracts/assigns.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Date: July 2021
1313

1414
#include "assigns.h"
1515

16+
#include <goto-instrument/havoc_utils.h>
17+
1618
#include <util/arith_tools.h>
1719
#include <util/c_types.h>
1820
#include <util/pointer_predicates.h>

src/goto-instrument/contracts/contracts.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*******************************************************************\
22
3-
Module: Verify and use annotated invariants and pre/post-conditions
3+
Module: Verify and use annotated loop and function contracts
44
55
Author: Michael Tautschnig
66
@@ -9,20 +9,19 @@ Date: February 2016
99
\*******************************************************************/
1010

1111
/// \file
12-
/// Verify and use annotated invariants and pre/post-conditions
12+
/// Verify and use annotated loop and function contracts
1313

1414
#include "contracts.h"
1515

16-
#include "assigns.h"
17-
#include "memory_predicates.h"
18-
1916
#include <algorithm>
2017
#include <map>
2118

2219
#include <analyses/local_may_alias.h>
2320

2421
#include <ansi-c/c_expr.h>
2522

23+
#include <goto-instrument/havoc_utils.h>
24+
2625
#include <goto-programs/remove_skip.h>
2726

2827
#include <util/c_types.h>
@@ -34,6 +33,9 @@ Date: February 2016
3433
#include <util/pointer_offset_size.h>
3534
#include <util/replace_symbol.h>
3635

36+
#include "assigns.h"
37+
#include "memory_predicates.h"
38+
3739
// Create a lexicographic less-than relation between two tuples of variables.
3840
// This is used in the implementation of multidimensional decreases clauses.
3941
static exprt create_lexicographic_less_than(
@@ -185,8 +187,8 @@ void code_contractst::check_apply_loop_contracts(
185187
"Check loop invariant before entry");
186188
}
187189

188-
// havoc variables being written to
189-
build_havoc_code(loop_head, modifies, havoc_code);
190+
// havoc the variables that may be modified
191+
append_havoc_code(loop_head->source_location, modifies, havoc_code);
190192

191193
// Generate: assume(invariant) just after havocing
192194
// We use a block scope to create a temporary assumption,

src/goto-instrument/havoc_loops.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com
1717
#include <goto-programs/remove_skip.h>
1818

1919
#include "function_modifies.h"
20+
#include "havoc_utils.h"
2021
#include "loop_utils.h"
2122

2223
class havoc_loopst
@@ -67,7 +68,7 @@ void havoc_loopst::havoc_loop(
6768

6869
// build the havocking code
6970
goto_programt havoc_code;
70-
build_havoc_code(loop_head, modifies, havoc_code);
71+
append_havoc_code(loop_head->source_location, modifies, havoc_code);
7172

7273
// Now havoc at the loop head. Use insert_swap to
7374
// preserve jumps to loop head.

src/goto-instrument/havoc_utils.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*******************************************************************\
2+
3+
Module: Utilities for building havoc code for expressions.
4+
5+
Author: Saswat Padhi, saspadhi@amazon.com
6+
7+
Date: July 2021
8+
9+
\*******************************************************************/
10+
11+
/// \file
12+
/// Utilities for building havoc code for expressions
13+
14+
#include "havoc_utils.h"
15+
16+
#include <util/expr_util.h>
17+
#include <util/pointer_expr.h>
18+
19+
class havoc_utils_is_constantt : public is_constantt
20+
{
21+
public:
22+
explicit havoc_utils_is_constantt(const modifiest &mod) : modifies(mod)
23+
{
24+
}
25+
bool is_constant(const exprt &expr) const override
26+
{
27+
// Besides the "usual" constants (checked in is_constantt::is_constant),
28+
// we also treat unmodified symbols as constants
29+
if(expr.id() == ID_symbol && modifies.find(expr) == modifies.end())
30+
return true;
31+
32+
return is_constantt::is_constant(expr);
33+
}
34+
35+
protected:
36+
const modifiest &modifies;
37+
};
38+
39+
void append_object_havoc_code_for_expr(
40+
const source_locationt source_location,
41+
const exprt &lhs,
42+
goto_programt &dest)
43+
{
44+
codet havoc(ID_havoc_object);
45+
havoc.add_source_location() = source_location;
46+
havoc.add_to_operands(lhs);
47+
48+
dest.add(goto_programt::make_other(havoc, source_location));
49+
}
50+
51+
void append_scalar_havoc_code_for_expr(
52+
const source_locationt source_location,
53+
const exprt &lhs,
54+
goto_programt &dest)
55+
{
56+
side_effect_expr_nondett rhs(lhs.type(), source_location);
57+
58+
goto_programt::targett t = dest.add(
59+
goto_programt::make_assignment(lhs, std::move(rhs), source_location));
60+
t->code_nonconst().add_source_location() = source_location;
61+
}
62+
63+
void append_havoc_code(
64+
const source_locationt source_location,
65+
const modifiest &modifies,
66+
goto_programt &dest)
67+
{
68+
havoc_utils_is_constantt is_constant(modifies);
69+
for(const auto &lhs : modifies)
70+
{
71+
if(lhs.id() == ID_index || lhs.id() == ID_dereference)
72+
{
73+
address_of_exprt address_of_lhs(lhs);
74+
if(!is_constant(address_of_lhs))
75+
{
76+
append_object_havoc_code_for_expr(source_location, address_of_lhs, dest);
77+
continue;
78+
}
79+
}
80+
81+
append_scalar_havoc_code_for_expr(source_location, lhs, dest);
82+
}
83+
}

src/goto-instrument/havoc_utils.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*******************************************************************\
2+
3+
Module: Utilities for building havoc code for expressions.
4+
5+
Author: Saswat Padhi, saspadhi@amazon.com
6+
7+
Date: July 2021
8+
9+
\*******************************************************************/
10+
11+
/// \file
12+
/// Utilities for building havoc code for expressions
13+
14+
#ifndef CPROVER_GOTO_INSTRUMENT_HAVOC_UTILS_H
15+
#define CPROVER_GOTO_INSTRUMENT_HAVOC_UTILS_H
16+
17+
#include <set>
18+
19+
#include <goto-programs/goto_program.h>
20+
21+
typedef std::set<exprt> modifiest;
22+
23+
void append_havoc_code(
24+
const source_locationt source_location,
25+
const modifiest &modifies,
26+
goto_programt &dest);
27+
28+
void append_object_havoc_code_for_expr(
29+
const source_locationt source_location,
30+
const exprt &expr,
31+
goto_programt &dest);
32+
33+
void append_scalar_havoc_code_for_expr(
34+
const source_locationt source_location,
35+
const exprt &expr,
36+
goto_programt &dest);
37+
38+
#endif // CPROVER_GOTO_INSTRUMENT_HAVOC_UTILS_H

src/goto-instrument/k_induction.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ Author: Daniel Kroening, kroening@kroening.com
1616

1717
#include <goto-programs/remove_skip.h>
1818

19-
#include "unwind.h"
19+
#include "havoc_utils.h"
2020
#include "loop_utils.h"
21+
#include "unwind.h"
2122

2223
class k_inductiont
2324
{
@@ -96,7 +97,7 @@ void k_inductiont::process_loop(
9697

9798
// build the havocking code
9899
goto_programt havoc_code;
99-
build_havoc_code(loop_head, modifies, havoc_code);
100+
append_havoc_code(loop_head->source_location, modifies, havoc_code);
100101

101102
// unwind to get k+1 copies
102103
std::vector<goto_programt::targett> iteration_points;

src/goto-instrument/loop_utils.cpp

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,12 @@ Author: Daniel Kroening, kroening@kroening.com
1111

1212
#include "loop_utils.h"
1313

14-
#include <util/expr_util.h>
15-
#include <util/pointer_expr.h>
16-
#include <util/std_expr.h>
17-
18-
#include <goto-programs/pointer_arithmetic.h>
19-
2014
#include <analyses/local_may_alias.h>
2115

22-
class loop_utils_is_constantt : public is_constantt
23-
{
24-
public:
25-
explicit loop_utils_is_constantt(const modifiest &mod) : modifies(mod)
26-
{
27-
}
28-
bool is_constant(const exprt &expr) const override
29-
{
30-
// Besides the "usual" constants (checked in is_constantt::is_constant),
31-
// we also treat unmodified symbols as constants
32-
if(expr.id() == ID_symbol && modifies.find(expr) == modifies.end())
33-
return true;
34-
35-
return is_constantt::is_constant(expr);
36-
}
16+
#include <goto-programs/pointer_arithmetic.h>
3717

38-
protected:
39-
const modifiest &modifies;
40-
};
18+
#include <util/pointer_expr.h>
19+
#include <util/std_expr.h>
4120

4221
goto_programt::targett get_loop_exit(const loopt &loop)
4322
{
@@ -57,51 +36,6 @@ goto_programt::targett get_loop_exit(const loopt &loop)
5736
return ++last;
5837
}
5938

60-
void build_havoc_code_for_scalar(
61-
const goto_programt::targett loop_head,
62-
const exprt &lhs,
63-
goto_programt &dest)
64-
{
65-
side_effect_expr_nondett rhs(lhs.type(), loop_head->source_location);
66-
67-
goto_programt::targett t = dest.add(goto_programt::make_assignment(
68-
lhs, std::move(rhs), loop_head->source_location));
69-
t->code_nonconst().add_source_location() = loop_head->source_location;
70-
}
71-
72-
void build_havoc_code_for_object(
73-
const goto_programt::targett loop_head,
74-
const exprt &lhs,
75-
goto_programt &dest)
76-
{
77-
codet havoc(ID_havoc_object);
78-
havoc.add_source_location() = loop_head->source_location;
79-
havoc.add_to_operands(lhs);
80-
81-
dest.add(goto_programt::make_other(havoc, loop_head->source_location));
82-
}
83-
84-
void build_havoc_code(
85-
const goto_programt::targett loop_head,
86-
const modifiest &modifies,
87-
goto_programt &dest)
88-
{
89-
loop_utils_is_constantt is_constant(modifies);
90-
for(const auto &lhs : modifies)
91-
{
92-
if(lhs.id() == ID_index || lhs.id() == ID_dereference)
93-
{
94-
address_of_exprt address_of_lhs(lhs);
95-
if(!is_constant(address_of_lhs))
96-
{
97-
build_havoc_code_for_object(loop_head, address_of_lhs, dest);
98-
continue;
99-
}
100-
}
101-
102-
build_havoc_code_for_scalar(loop_head, lhs, dest);
103-
}
104-
}
10539

10640
void get_modifies_lhs(
10741
const local_may_aliast &local_may_alias,

src/goto-instrument/loop_utils.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ void get_modifies_lhs(
3030
const exprt &lhs,
3131
modifiest &modifies);
3232

33-
void build_havoc_code(
34-
const goto_programt::targett loop_head,
35-
const modifiest &modifies,
36-
goto_programt &dest);
37-
3833
goto_programt::targett get_loop_exit(const loopt &);
3934

4035
#endif // CPROVER_GOTO_INSTRUMENT_LOOP_UTILS_H

0 commit comments

Comments
 (0)