Skip to content

Commit d0d2522

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

File tree

9 files changed

+143
-84
lines changed

9 files changed

+143
-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: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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+
void append_object_havoc_code_for_expr(
20+
const source_locationt source_location,
21+
const exprt &expr,
22+
goto_programt &dest)
23+
{
24+
codet havoc(ID_havoc_object);
25+
havoc.add_source_location() = source_location;
26+
havoc.add_to_operands(expr);
27+
dest.add(goto_programt::make_other(havoc, source_location));
28+
}
29+
30+
void append_scalar_havoc_code_for_expr(
31+
const source_locationt source_location,
32+
const exprt &expr,
33+
goto_programt &dest)
34+
{
35+
side_effect_expr_nondett rhs(expr.type(), source_location);
36+
goto_programt::targett t = dest.add(
37+
goto_programt::make_assignment(expr, std::move(rhs), source_location));
38+
t->code_nonconst().add_source_location() = source_location;
39+
}
40+
41+
void append_havoc_code(
42+
const source_locationt source_location,
43+
const modifiest &modifies,
44+
goto_programt &dest)
45+
{
46+
havoc_utils_is_constantt is_constant(modifies);
47+
for(const auto &expr : modifies)
48+
{
49+
if(expr.id() == ID_index || expr.id() == ID_dereference)
50+
{
51+
address_of_exprt address_of_expr(expr);
52+
if(!is_constant(address_of_expr))
53+
{
54+
append_object_havoc_code_for_expr(
55+
source_location, address_of_expr, dest);
56+
continue;
57+
}
58+
}
59+
60+
append_scalar_havoc_code_for_expr(source_location, expr, dest);
61+
}
62+
}

src/goto-instrument/havoc_utils.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
#include <util/expr_util.h>
22+
23+
typedef std::set<exprt> modifiest;
24+
25+
class havoc_utils_is_constantt : public is_constantt
26+
{
27+
public:
28+
explicit havoc_utils_is_constantt(const modifiest &mod) : modifies(mod)
29+
{
30+
}
31+
32+
bool is_constant(const exprt &expr) const override
33+
{
34+
// Besides the "usual" constants (checked in is_constantt::is_constant),
35+
// we also treat unmodified symbols as constants
36+
if(expr.id() == ID_symbol && modifies.find(expr) == modifies.end())
37+
return true;
38+
39+
return is_constantt::is_constant(expr);
40+
}
41+
42+
protected:
43+
const modifiest &modifies;
44+
};
45+
46+
void append_havoc_code(
47+
const source_locationt source_location,
48+
const modifiest &modifies,
49+
goto_programt &dest);
50+
51+
void append_object_havoc_code_for_expr(
52+
const source_locationt source_location,
53+
const exprt &expr,
54+
goto_programt &dest);
55+
56+
void append_scalar_havoc_code_for_expr(
57+
const source_locationt source_location,
58+
const exprt &expr,
59+
goto_programt &dest);
60+
61+
#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)