CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
java_trace_validation.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Java trace validation
4
5Author: Jeannie Moulton
6
7\*******************************************************************/
8
10
11#include <algorithm>
12
14
15#include <util/byte_operators.h>
16#include <util/expr_util.h>
17#include <util/pointer_expr.h>
18#include <util/simplify_expr.h>
19#include <util/std_expr.h>
20
22{
23 const auto symbol = expr_try_dynamic_cast<symbol_exprt>(expr);
24 return symbol && !symbol->get_identifier().empty();
25}
26
38
39std::optional<symbol_exprt> get_inner_symbol_expr(exprt expr)
40{
41 while(expr.has_operands())
42 {
43 expr = to_multi_ary_expr(expr).op0();
44 if(!may_be_lvalue(expr))
45 return {};
46 }
47 if(!check_symbol_structure(expr))
48 return {};
50}
51
53{
54 if(!expr.has_operands())
55 return false;
56 const auto symbol_operand = get_inner_symbol_expr(expr);
57 return symbol_operand.has_value();
58}
59
66
77
85
94
96{
97 if(!expr.has_operands())
98 return false;
101 else if(
104 {
105 return false;
106 }
107
108 return expr.operands().size() == 1 ||
109 std::all_of(
110 std::next(expr.operands().begin()),
111 expr.operands().end(),
112 [&](const exprt &operand) {
113 return can_cast_expr<constant_exprt>(operand) ||
114 can_cast_expr<annotated_pointer_constant_exprt>(operand);
115 });
116}
117
119{
120 const auto symbol_expr = get_inner_symbol_expr(address);
121 return symbol_expr && check_symbol_structure(*symbol_expr);
122}
123
125{
126 if(constant_expr.has_operands())
127 return false;
128 // All value types used in Java must be non-empty except string_typet:
129 return !constant_expr.get_value().empty() ||
130 constant_expr.type() == string_typet();
131}
132
141
143 const exprt &lhs,
144 const namespacet &ns,
145 const validation_modet vm)
146{
148 vm,
150 "LHS",
151 lhs.pretty(),
152 "Unsupported expression.");
153 // check member lhs structure
154 if(const auto member = expr_try_dynamic_cast<member_exprt>(lhs))
155 {
157 vm,
158 check_member_structure(*member),
159 "LHS",
160 lhs.pretty(),
161 "Expecting a member with nested symbol operand.");
162 }
163 // check symbol lhs structure
164 else if(const auto symbol = expr_try_dynamic_cast<symbol_exprt>(lhs))
165 {
167 vm,
168 check_symbol_structure(*symbol),
169 "LHS",
170 lhs.pretty(),
171 "Expecting a symbol with non-empty identifier.");
172 }
173 // check index lhs structure
174 else if(const auto index = expr_try_dynamic_cast<index_exprt>(lhs))
175 {
177 vm,
178 check_index_structure(*index),
179 "LHS",
180 lhs.pretty(),
181 "Expecting an index expression with a symbol array and constant or "
182 "symbol index value.");
183 }
184 // check byte extract lhs structure
185 else if(const auto byte = expr_try_dynamic_cast<byte_extract_exprt>(lhs))
186 {
188 vm,
190 "LHS",
191 lhs.pretty(),
192 "Expecting a byte extract expression with a symbol array and constant or "
193 "symbol index value.");
194 }
195 else
196 {
198 vm,
199 false,
200 "LHS",
201 lhs.pretty(),
202 "Expression does not meet any trace assumptions.");
203 }
204}
205
207 const exprt &rhs,
208 const namespacet &ns,
209 const validation_modet vm)
210{
212 vm,
214 "RHS",
215 rhs.pretty(),
216 "Unsupported expression.");
217 // check address_of rhs structure (String only)
218 if(const auto address = expr_try_dynamic_cast<address_of_exprt>(rhs))
219 {
221 vm,
222 check_address_structure(*address),
223 "RHS",
224 rhs.pretty(),
225 "Expecting an address of with nested symbol.");
226 }
227 // check symbol rhs structure (String only)
228 else if(const auto symbol_expr = expr_try_dynamic_cast<symbol_exprt>(rhs))
229 {
231 vm,
232 check_symbol_structure(*symbol_expr),
233 "RHS",
234 rhs.pretty(),
235 "Expecting a symbol with non-empty identifier.");
236 }
237 // check struct rhs structure
238 else if(const auto struct_expr = expr_try_dynamic_cast<struct_exprt>(rhs))
239 {
241 vm,
243 "RHS",
244 rhs.pretty(),
245 "Expecting all non-base class operands to be constants.");
246 }
247 // check array rhs structure
248 else if(can_cast_expr<array_exprt>(rhs))
249 {
250 // seems no check is required.
251 }
252 // check array rhs structure
254 {
255 // seems no check is required.
256 }
257 // check constant rhs structure
259 {
261 vm,
263 "RHS",
264 rhs.pretty(),
265 "Expecting a constant expression to have no operands and a non-empty "
266 "value.");
267 }
268 // check pointer constant rhs structure
269 else if(
270 const auto constant_expr =
272 {
274 vm,
276 "RHS",
277 rhs.pretty(),
278 "Expecting the operand of an annotated pointer constant expression "
279 "to be a constant, address_of, or plus expression.");
280 }
281 // check byte extract rhs structure
282 else if(const auto byte = expr_try_dynamic_cast<byte_extract_exprt>(rhs))
283 {
284 check_rhs_assumptions(simplify_expr(byte->op(), ns), ns, vm);
286 vm,
288 "RHS",
289 rhs.pretty(),
290 "Expecting a byte extract with constant index.");
291 }
292 else
293 {
295 vm,
296 false,
297 "RHS",
298 rhs.pretty(),
299 "Expression does not meet any trace assumptions.");
300 }
301}
302
304 const goto_trace_stept &step,
305 const namespacet &ns,
306 const validation_modet vm)
307{
308 if(!step.is_assignment() && !step.is_decl())
309 return;
312}
313
315 const goto_tracet &trace,
316 const namespacet &ns,
317 const messaget &log,
318 const bool run_check,
319 const validation_modet vm)
320{
321 if(!run_check)
322 return;
323 for(const auto &step : trace.steps)
324 check_step_assumptions(step, ns, vm);
325 log.status() << "Trace validation successful" << messaget::eom;
326}
Expression classes for byte-level operators.
bool can_cast_expr< byte_extract_exprt >(const exprt &base)
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Pointer-typed bitvector constant annotated with the pointer expression that the bitvector is the nume...
A constant literal expression.
Definition std_expr.h:3117
Base class for all expressions.
Definition expr.h:56
bool has_operands() const
Return true if there is at least one operand.
Definition expr.h:91
operandst & operands()
Definition expr.h:94
Step of the trace of a GOTO program.
Definition goto_trace.h:50
bool is_assignment() const
Definition goto_trace.h:55
bool is_decl() const
Definition goto_trace.h:65
Trace of a GOTO program.
Definition goto_trace.h:177
stepst steps
Definition goto_trace.h:180
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition irep.cpp:482
Extract member of struct or union.
Definition std_expr.h:2971
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
static eomt eom
Definition message.h:289
exprt & op0()
Definition std_expr.h:932
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
String type.
Definition std_types.h:966
Struct constructor from list of elements.
Definition std_expr.h:1877
const exprt & skip_typecast(const exprt &expr)
find the expression nested inside typecasts, if any
Deprecated expression utility functions.
Traces of GOTO Programs.
bool valid_lhs_expr_high_level(const exprt &lhs)
static void check_step_assumptions(const goto_trace_stept &step, const namespacet &ns, const validation_modet vm)
std::optional< symbol_exprt > get_inner_symbol_expr(exprt expr)
Recursively extracts the first operand of an expression until it reaches a symbol and returns it,...
bool check_address_structure(const address_of_exprt &address)
bool valid_rhs_expr_high_level(const exprt &rhs)
bool check_member_structure(const member_exprt &expr)
static bool check_annotated_pointer_constant_structure(const annotated_pointer_constant_exprt &constant_expr)
bool check_index_structure(const exprt &index_expr)
bool check_symbol_structure(const exprt &expr)
static bool may_be_lvalue(const exprt &expr)
void check_trace_assumptions(const goto_tracet &trace, const namespacet &ns, const messaget &log, const bool run_check, const validation_modet vm)
Checks that the structure of each step of the trace matches certain criteria.
bool check_constant_structure(const constant_exprt &constant_expr)
static void check_lhs_assumptions(const exprt &lhs, const namespacet &ns, const validation_modet vm)
static void check_rhs_assumptions(const exprt &rhs, const namespacet &ns, const validation_modet vm)
bool can_evaluate_to_constant(const exprt &expression)
bool check_struct_structure(const struct_exprt &expr)
double log(double x)
Definition math.c:2449
API to expression classes for Pointers.
bool can_cast_expr< annotated_pointer_constant_exprt >(const exprt &base)
bool can_cast_expr< address_of_exprt >(const exprt &base)
exprt simplify_expr(exprt src, const namespacet &ns)
API to expression classes.
bool can_cast_expr< typecast_exprt >(const exprt &base)
Definition std_expr.h:2091
bool can_cast_expr< struct_exprt >(const exprt &base)
Definition std_expr.h:1889
bool can_cast_expr< mult_exprt >(const exprt &base)
Definition std_expr.h:1121
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition std_expr.h:715
bool can_cast_expr< plus_exprt >(const exprt &base)
Definition std_expr.h:1025
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition std_expr.h:987
bool can_cast_expr< constant_exprt >(const exprt &base)
Definition std_expr.h:3156
bool can_cast_expr< index_exprt >(const exprt &base)
Definition std_expr.h:1522
bool can_cast_expr< symbol_exprt >(const exprt &base)
Definition std_expr.h:256
bool can_cast_expr< member_exprt >(const exprt &base)
Definition std_expr.h:3047
bool can_cast_expr< array_list_exprt >(const exprt &base)
Definition std_expr.h:1706
bool can_cast_expr< array_exprt >(const exprt &base)
Definition std_expr.h:1654
#define DATA_CHECK_WITH_DIAGNOSTICS(vm, condition, message,...)
Definition validate.h:37
validation_modet