CBMC
havoc_assigns_clause_targets.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Havoc multiple and possibly dependent targets simultaneously
4 
5 Author: Remi Delmas, delmasrd@amazon.com
6 
7 \*******************************************************************/
8 
11 
13 
14 #include <util/c_types.h>
15 #include <util/format_expr.h>
16 #include <util/format_type.h>
17 #include <util/message.h>
18 #include <util/pointer_expr.h>
21 #include <util/std_code.h>
22 
23 #include <ansi-c/c_expr.h>
24 #include <langapi/language_util.h>
25 
27 #include "utils.h"
28 
29 #include <map>
30 
32 {
33  // snapshotting instructions and well-definedness checks
34  goto_programt snapshot_program;
35 
36  // add static locals called touched by the replaced function
37  track_static_locals(snapshot_program);
38 
39  // add spec targets
40  for(const auto &target : targets)
41  track_spec_target(target, snapshot_program);
42 
43  // generate havocking instructions for all tracked CARs
44  goto_programt havoc_program;
45  for(const auto &pair : from_spec_assigns)
46  havoc_if_valid(pair.second, havoc_program);
47 
48  for(const auto &pair : from_stack_alloc)
49  havoc_if_valid(pair.second, havoc_program);
50 
51  for(const auto &car : from_heap_alloc)
52  havoc_if_valid(car, havoc_program);
53 
54  for(const auto &pair : from_static_local)
55  {
56  havoc_static_local(pair.second, havoc_program);
57  }
58 
59  // append to dest
60  dest.destructive_append(snapshot_program);
61  dest.destructive_append(havoc_program);
62 }
63 
65  car_exprt car,
66  goto_programt &dest)
67 {
68  const irep_idt &tracking_comment =
70  car.target(), function_id, ns);
71 
72  source_locationt source_location_no_checks(source_location);
73  add_pragma_disable_pointer_checks(source_location_no_checks);
74 
75  goto_programt skip_program;
76  const auto skip_target =
77  skip_program.add(goto_programt::make_skip(source_location_no_checks));
78 
80  skip_target, not_exprt{car.valid_var()}, source_location_no_checks));
81 
83  {
84  // OTHER __CPROVER_havoc_object(target_snapshot_var)
85  codet code(ID_havoc_object, {car.lower_bound_var()});
86  const auto &inst =
88  inst->source_location_nonconst().set_comment(tracking_comment);
89  }
91  {
92  // This is a slice target. We use goto convert's do_havoc_slice()
93  // code generation, provided by cleanert.
94  cleanert cleaner(st, log.get_message_handler());
95  const auto &mode = st.lookup_ref(function_id).mode;
96  const auto &funcall = to_side_effect_expr_function_call(car.target());
97  const auto &function = to_symbol_expr(funcall.function());
98  exprt::operandst arguments;
99  arguments.push_back(car.lower_bound_var());
100  arguments.push_back(car.target_size());
101  cleaner.do_havoc_slice(function, arguments, dest, mode);
102  }
104  {
105  // a target where the size is derived from the type of the target
106  // ASSIGN *(target.type() *)__car_lb = nondet(car.target().type())
107  const auto &target_type = car.target().type();
108  side_effect_expr_nondett nondet(target_type, source_location);
109  const auto &inst = dest.add(goto_programt::make_assignment(
111  car.lower_bound_var(), pointer_type(target_type))},
112  nondet,
113  source_location));
114  inst->source_location_nonconst().set_comment(tracking_comment);
115  }
116  else
117  {
118  UNREACHABLE;
119  }
120 
121  dest.destructive_append(skip_program);
122 
123  dest.add(
124  goto_programt::make_dead(car.valid_var(), source_location_no_checks));
125 
126  dest.add(
127  goto_programt::make_dead(car.lower_bound_var(), source_location_no_checks));
128 
129  dest.add(
130  goto_programt::make_dead(car.upper_bound_var(), source_location_no_checks));
131 }
132 
134  car_exprt car,
135  goto_programt &dest)
136 {
137  // We havoc the target expression directly for local statics
138  // instead of the __car_lb pointer because we know statics never die
139  // and cannot be involved in in dependencies
140  // since we cannot talk about them in contracts.
141  const irep_idt &tracking_comment =
143  car.target(), function_id, ns);
144 
145  source_locationt source_location_no_checks(source_location);
146  add_pragma_disable_pointer_checks(source_location_no_checks);
147 
148  goto_programt skip_program;
149  const auto skip_target =
150  skip_program.add(goto_programt::make_skip(source_location_no_checks));
151 
153  skip_target, not_exprt{car.valid_var()}, source_location_no_checks));
154 
155  const auto &target_type = car.target().type();
156  side_effect_expr_nondett nondet(target_type, source_location);
157  const auto &inst = dest.add(
159  inst->source_location_nonconst().set_comment(tracking_comment);
160  add_propagate_static_local_pragma(inst->source_location_nonconst());
161 
162  dest.destructive_append(skip_program);
163 
164  dest.add(
165  goto_programt::make_dead(car.valid_var(), source_location_no_checks));
166 
167  dest.add(
168  goto_programt::make_dead(car.lower_bound_var(), source_location_no_checks));
169 
170  dest.add(
171  goto_programt::make_dead(car.upper_bound_var(), source_location_no_checks));
172 }
goto_programt::make_other
static instructiont make_other(const goto_instruction_codet &_code, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:948
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
havoc_assigns_clause_targetst::havoc_if_valid
void havoc_if_valid(car_exprt car, goto_programt &dest)
Generates instructions to conditionally havoc the given conditional address range expression car,...
Definition: havoc_assigns_clause_targets.cpp:64
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
instrument_spec_assignst::from_spec_assigns
cond_target_exprt_to_car_mapt from_spec_assigns
Map from conditional target expressions of assigns clauses to corresponding conditional address range...
Definition: instrument_spec_assigns.h:612
symbol_table_baset::lookup_ref
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Definition: symbol_table_base.h:104
to_side_effect_expr_function_call
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
Definition: std_code.h:1739
havoc_assigns_clause_targetst::get_instructions
void get_instructions(goto_programt &dest)
Generates the assigns clause replacement instructions in dest.
Definition: havoc_assigns_clause_targets.cpp:31
goto_programt::make_dead
static instructiont make_dead(const symbol_exprt &symbol, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:962
havoc_assigns_clause_targetst::havoc_static_local
void havoc_static_local(car_exprt car, goto_programt &dest)
Havoc a static local expression.
Definition: havoc_assigns_clause_targets.cpp:133
havoc_assigns_clause_targetst::source_location
const source_locationt & source_location
Definition: havoc_assigns_clause_targets.h:123
make_assigns_clause_replacement_tracking_comment
irep_idt make_assigns_clause_replacement_tracking_comment(const exprt &target, const irep_idt &function_id, const namespacet &ns)
Returns an irep_idt that essentially says that target was assigned by the contract of function_id.
Definition: utils.cpp:231
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
car_exprt::havoc_method
const car_havoc_methodt havoc_method
Method to use to havod the target.
Definition: instrument_spec_assigns.h:104
instrument_spec_assignst::from_stack_alloc
symbol_exprt_to_car_mapt from_stack_alloc
Map from DECL symbols to corresponding conditional address ranges.
Definition: instrument_spec_assigns.h:621
pointer_predicates.h
goto_programt::add
targett add(instructiont &&instruction)
Adds a given instruction at the end.
Definition: goto_program.h:709
havoc_assigns_clause_targetst::targets
const std::vector< exprt > & targets
Definition: havoc_assigns_clause_targets.h:122
instrument_spec_assignst::from_static_local
symbol_exprt_to_car_mapt from_static_local
Map to from detected or propagated static local symbols to corresponding conditional address ranges.
Definition: instrument_spec_assigns.h:636
car_exprt::target_size
const exprt & target_size() const
Size of the target in bytes.
Definition: instrument_spec_assigns.h:125
car_exprt::lower_bound_var
const symbol_exprt & lower_bound_var() const
Identifier of the lower address bound snapshot variable.
Definition: instrument_spec_assigns.h:137
car_havoc_methodt::HAVOC_OBJECT
@ HAVOC_OBJECT
goto_programt::make_assignment
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
Definition: goto_program.h:1056
goto_programt::make_goto
static instructiont make_goto(targett _target, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:1030
instrument_spec_assignst::log
messaget log
Logger.
Definition: instrument_spec_assigns.h:492
cleanert
Allows to clean expressions of side effects.
Definition: utils.h:147
add_pragma_disable_pointer_checks
void add_pragma_disable_pointer_checks(source_locationt &location)
Adds a pragma on a source location disable all pointer checks.
Definition: instrument_spec_assigns.cpp:51
instrument_spec_assignst::function_id
const irep_idt & function_id
Name of the instrumented function.
Definition: instrument_spec_assigns.h:477
car_exprt::upper_bound_var
const symbol_exprt & upper_bound_var() const
Identifier of the upper address bound snapshot variable.
Definition: instrument_spec_assigns.h:143
car_exprt::valid_var
const symbol_exprt & valid_var() const
Identifier of the validity snapshot variable.
Definition: instrument_spec_assigns.h:131
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
instrument_spec_assignst::ns
const namespacet ns
Program namespace.
Definition: instrument_spec_assigns.h:489
utils.h
symbolt::mode
irep_idt mode
Language mode.
Definition: symbol.h:49
car_havoc_methodt::NONDET_ASSIGN
@ NONDET_ASSIGN
goto_programt::make_skip
static instructiont make_skip(const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:882
language_util.h
instrument_spec_assignst::st
symbol_tablet & st
Program symbol table.
Definition: instrument_spec_assigns.h:486
c_expr.h
pointer_expr.h
add_propagate_static_local_pragma
void add_propagate_static_local_pragma(source_locationt &source_location)
Sets a pragma to mark assignments to static local variables that need to be propagated upwards in the...
Definition: instrument_spec_assigns.cpp:42
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
instrument_spec_assignst::mode
const irep_idt & mode
Language mode.
Definition: instrument_spec_assigns.h:495
instrument_spec_assignst::from_heap_alloc
car_expr_listt from_heap_alloc
Definition: instrument_spec_assigns.h:630
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
std_code.h
goto_programt::destructive_append
void destructive_append(goto_programt &p)
Appends the given program p to *this. p is destroyed.
Definition: goto_program.h:692
source_locationt
Definition: source_location.h:18
side_effect_expr_nondett
A side_effect_exprt that returns a non-deterministically chosen value.
Definition: std_code.h:1519
messaget::get_message_handler
message_handlert & get_message_handler()
Definition: message.h:184
format_expr.h
instrument_spec_assignst::track_static_locals
void track_static_locals(goto_programt &dest)
Searches the goto instructions reachable from the start to the end of the instrumented function's ins...
Definition: instrument_spec_assigns.cpp:155
cleanert::do_havoc_slice
void do_havoc_slice(const symbol_exprt &function, const exprt::operandst &arguments, goto_programt &dest, const irep_idt &mode)
Definition: utils.h:162
car_havoc_methodt::HAVOC_SLICE
@ HAVOC_SLICE
car_exprt::target
const exprt & target() const
The target expression.
Definition: instrument_spec_assigns.h:113
instrument_spec_assigns.h
havoc_assigns_clause_targets.h
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:72
instrument_spec_assignst::track_spec_target
void track_spec_target(const exprt &expr, goto_programt &dest)
Track an assigns clause target and generate snaphsot instructions and well-definedness assertions in ...
Definition: instrument_spec_assigns.cpp:89
car_exprt
Class that represents a normalized conditional address range, with:
Definition: instrument_spec_assigns.h:76
message.h
c_types.h
format_type.h
codet
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:28
not_exprt
Boolean negation.
Definition: std_expr.h:2277