ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
dynamic_type_handler.h
Go to the documentation of this file.
1#pragma once
2
3#include <util/irep/type.h>
4#include <util/irep/expr.h>
9#include <nlohmann/json.hpp>
10#include <string>
11#include <unordered_map>
12#include <unordered_set>
13#include <vector>
14
16class type_handler;
17
19{
20public:
22
30 std::unordered_set<std::string>
31 detect_dynamic_type_names(const nlohmann::json &if_node) const;
32
39 const std::unordered_set<std::string> &dynamic_type_names,
40 const nlohmann::json &ast_node);
41
47 bool is_tagged(const std::string &name) const;
48
53 std::string tagged_symbol_id(const std::string &name) const;
54
59 symbol_id bound_symbol_id(const std::string &name) const;
60
66 bool tagged_binop_result_may_be_tagged(const std::string &op) const;
67
72 void assign(
73 const exprt &rhs,
74 const locationt &location,
75 const std::string &name,
76 codet &target_block);
77
82 void resolve_read(symbolt *&symbol) const;
83
88 exprt
89 handle_comparison(const std::string &op, const exprt &lhs, const exprt &rhs);
90
96 const std::string &op,
97 const exprt &lhs,
98 const exprt &rhs,
99 const locationt &location);
100
106 void guard_type_error(
107 const std::string &op,
108 const exprt &lhs,
109 const exprt &rhs,
110 const locationt &location);
111
116 exprt build_neg_tagged(const exprt &tagged, const locationt &location);
117
124 const exprt &tagged,
125 const std::string &type_name,
126 bool type_is_user_class) const;
127
129 exprt build_truthiness(const exprt &tagged);
130
137 bool detect_dynamic_return_type(const nlohmann::json &function_node) const;
138
141 bool parameter_call_returns_tagged(const nlohmann::json &call) const;
142
149 const std::string &name,
150 const nlohmann::json &scope_body,
151 const nlohmann::json &module_body = nlohmann::json()) const;
152
158 const exprt &value,
159 const locationt &location,
160 codet &target_block);
161
168 const exprt &tagged,
169 const typet &result_type,
170 const locationt &location);
171
174 void refuse_float_tag_operation(const exprt &lhs, const exprt &rhs) const;
175
177 [[noreturn]] void refuse_tagged_argument() const;
178
184 const exprt &rhs,
185 const locationt &location,
186 const std::string &name,
187 codet &target_block);
188
195 {
196 public:
198 dynamic_type_handler &handler,
199 const std::unordered_set<std::string> &dynamic_type_names);
200 ~scope_guard();
201
202 private:
203 dynamic_type_handler &handler_;
204 std::unordered_set<std::string> added_;
205 };
206
207private:
215 std::vector<codet> build_tag_field_assigns(
216 symbolt &tag_symbol,
217 const exprt &rhs,
218 const locationt &location);
219
225 symbolt *find_tag_symbol(const std::string &name) const;
226
232 bool joins_divergent_kinds(
233 const std::string &name,
234 std::unordered_set<std::string> &kinds,
235 bool keeps_value) const;
236
242 exprt build_literal_compare_call(
243 const std::string &num_func_name,
244 const std::string &str_func_name,
245 const exprt &tagged,
246 const exprt &literal);
247
248 exprt build_eq_literal(const exprt &tagged, const exprt &literal);
249 exprt build_ordered_literal(
250 const std::string &op,
251 const exprt &tagged,
252 const exprt &literal);
253 exprt
254 build_ordered_obj(const std::string &op, const exprt &lhs, const exprt &rhs);
255 exprt build_add_literal(
256 const exprt &tagged,
257 const exprt &literal,
258 bool tagged_is_left);
259 exprt build_sub_literal(
260 const exprt &tagged,
261 const exprt &literal,
262 bool tagged_is_left);
263 exprt build_div_literal(
264 const exprt &tagged,
265 const exprt &literal,
266 bool tagged_is_left,
267 const locationt &location);
268 exprt build_add_tagged(const exprt &lhs, const exprt &rhs);
269 exprt build_sub_tagged(const exprt &lhs, const exprt &rhs);
270 exprt build_div_tagged(
271 const exprt &lhs,
272 const exprt &rhs,
273 const locationt &location);
274
279 exprt operands_type_ok(
280 const std::string &op,
281 const exprt &lhs,
282 const exprt &rhs) const;
283
288 void guard_zero_division(
289 const exprt &divisor,
290 const exprt &type_ok,
291 const locationt &location);
292
293 python_converter &converter_;
294 type_handler &type_handler_;
295
296 // Names of variables flagged as needing the tagged-object representation
297 // for the duration of converting one if/else's branches.
298 std::unordered_set<std::string> tagged_names_;
299
300 // Original symbol id -> tagged-object symbol id, for a variable that
301 // already had a native-typed symbol when it was flagged. Unlike the
302 // straight-line retype heuristic's alias, never reverted: the whole
303 // point is surviving the join.
304 std::unordered_map<std::string, std::string> aliases_;
305};
Definition std_code.h:8
~scope_guard()
Definition dynamic_type_handler.cpp:1685
scope_guard(dynamic_type_handler &handler, const std::unordered_set< std::string > &dynamic_type_names)
Definition dynamic_type_handler.cpp:1675
bool is_tagged(const std::string &name) const
True if name currently resolves to a tagged-object symbol, either because it is one of the current if...
Definition dynamic_type_handler.cpp:769
std::unordered_set< std::string > detect_dynamic_type_names(const nlohmann::json &if_node) const
Names assigned genuinely incompatible literal types across every branch of if_node,...
Definition dynamic_type_handler.cpp:594
symbol_id bound_symbol_id(const std::string &name) const
The id of the symbol name binds in the scope being converted: a variable, or class C's own attribute ...
Definition dynamic_type_handler.cpp:754
exprt build_neg_tagged(const exprt &tagged, const locationt &location)
Builds unary minus on a tagged-scalar operand, as 0 - tagged, after guard_type_error for that subtrac...
Definition dynamic_type_handler.cpp:1226
dynamic_type_handler(python_converter &converter, type_handler &type_handler)
Definition dynamic_type_handler.cpp:587
exprt build_tagged_value(const exprt &value, const locationt &location, codet &target_block)
Builds a tagged-object temporary from an already-converted value, for use as either a RETURN value or...
Definition dynamic_type_handler.cpp:1494
void assign(const exprt &rhs, const locationt &location, const std::string &name, codet &target_block)
Fills in the tagged-object fields for name from an already-converted value.
Definition dynamic_type_handler.cpp:898
exprt build_numeric_conversion(const exprt &tagged, const typet &result_type, const locationt &location)
int(tagged) or float(tagged), as result_type says: a str is parsed at runtime and raises ValueError w...
Definition dynamic_type_handler.cpp:1516
exprt handle_comparison(const std::string &op, const exprt &lhs, const exprt &rhs)
Dispatches Eq/NotEq/Lt/LtE/Gt/GtE between a tagged-scalar operand and the other side.
Definition dynamic_type_handler.cpp:973
void resolve_read(symbolt *&symbol) const
Redirects symbol to its tagged-object alias, if a pre-existing variable was aliased for it; no-op oth...
Definition dynamic_type_handler.cpp:910
void refuse_tagged_argument() const
Throws the shared "tagged argument, no known parameter type" refusal.
Definition dynamic_type_handler.cpp:1655
void assign_tagged_object(const exprt &rhs, const locationt &location, const std::string &name, codet &target_block)
Whole-struct copy: fills name's tagged-object symbol from a value that is already tagged-object-typed...
Definition dynamic_type_handler.cpp:1662
bool parameter_call_returns_tagged(const nlohmann::json &call) const
call goes through a parameter of the current function, and every call of that function passes a def r...
Definition dynamic_type_handler.cpp:1466
void refuse_float_tag_operation(const exprt &lhs, const exprt &rhs) const
Throws when a tag may hold a float and lhs op rhs is not a str operation.
Definition dynamic_type_handler.cpp:1641
std::string tagged_symbol_id(const std::string &name) const
The id of the symbol that currently holds name's tagged object, following the alias created for a pre...
Definition dynamic_type_handler.cpp:783
void declare_dynamic_type_names(const std::unordered_set< std::string > &dynamic_type_names, const nlohmann::json &ast_node)
Declares (or aliases) each name's tagged-object symbol before either branch converts,...
Definition dynamic_type_handler.cpp:668
exprt build_truthiness(const exprt &tagged)
Python truthiness of a tagged value, decided by its runtime type.
Definition dynamic_type_handler.cpp:1452
exprt handle_arithmetic(const std::string &op, const exprt &lhs, const exprt &rhs, const locationt &location)
Dispatches Add/Sub/Div between a tagged-scalar operand and a literal.
Definition dynamic_type_handler.cpp:1191
bool scope_assigns_divergent_literal_types(const std::string &name, const nlohmann::json &scope_body, const nlohmann::json &module_body=nlohmann::json()) const
True if some top-level If in scope_body (a function body or the module body) assigns name genuinely i...
Definition dynamic_type_handler.cpp:1485
bool detect_dynamic_return_type(const nlohmann::json &function_node) const
True if a function's top-level if/elif/else chain – including an early return with no else,...
Definition dynamic_type_handler.cpp:1479
exprt build_isinstance_check(const exprt &tagged, const std::string &type_name, bool type_is_user_class) const
Builds isinstance(tagged, type_name).
Definition dynamic_type_handler.cpp:1402
bool tagged_binop_result_may_be_tagged(const std::string &op) const
True if op on two tagged operands can produce either scalar type at runtime (only '+' today); an unta...
Definition dynamic_type_handler.cpp:790
void guard_type_error(const std::string &op, const exprt &lhs, const exprt &rhs, const locationt &location)
Inside a try body, raises a catchable TypeError ahead of an Add/Sub/Div or ordered comparison on the ...
Definition dynamic_type_handler.cpp:1363
Definition expr.h:34
Definition location.h:7
Main converter for transforming Python AST into ESBMC's intermediate representation.
Definition python_converter.h:76
Definition symbol_id.h:6
Definition symbol.h:12
Definition type_handler.h:113
Definition type.h:9
Definition toml.hpp:1531