170 conditiont(
const exprt &_assertion,
const std::string &_description)
171 : assertion(_assertion), description(_description)
176 std::string description;
179 using conditionst = std::list<conditiont>;
181 void bounds_check(
const exprt &,
const guardt &);
182 void bounds_check_index(
const index_exprt &,
const guardt &);
183 void bounds_check_bit_count(
const unary_exprt &,
const guardt &);
184 void div_by_zero_check(
const div_exprt &,
const guardt &);
185 void float_div_by_zero_check(
const div_exprt &,
const guardt &);
186 void mod_by_zero_check(
const mod_exprt &,
const guardt &);
187 void mod_overflow_check(
const mod_exprt &,
const guardt &);
189 void undefined_shift_check(
const shift_exprt &,
const guardt &);
190 void pointer_rel_check(
const binary_exprt &,
const guardt &);
191 void pointer_overflow_check(
const exprt &,
const guardt &);
192 void memory_leak_check(
const irep_idt &function_id);
200 const dereference_exprt &expr,
201 const exprt &src_expr,
219 std::optional<goto_check_ct::conditiont>
222 const exprt &address,
225 const exprt &pointer,
229 const exprt &address,
248 const exprt &asserted_expr,
250 const std::string &property_class,
252 const source_locationt &source_location,
253 const exprt &src_expr,
374 "Flag " +
id2string(flag_name) +
" set twice at \n" +
376 if(flag != new_value)
391 "Flag " +
id2string(flag_name) +
" disabled twice at \n" +
412 *flag_pair.first = flag_pair.second;
424 if(rhs.
id() == ID_implies)
428 and_exprt(std::move(lhs), rhs_implication.lhs()), rhs_implication.rhs());
440 for(
const auto &instruction : gf_entry.second.body.instructions)
442 if(!instruction.is_function_call())
445 const auto &function = instruction.call_function();
447 function.id() != ID_symbol ||
to_symbol_expr(function).identifier() !=
452 instruction.call_arguments();
454 args.size() != 2 || args[0].type().id() != ID_unsignedbv ||
455 args[1].type().id() != ID_unsignedbv)
460 args[0].type() == args[1].type(),
461 "arguments of allocated_memory must have same type");
469 if(lhs.
id() == ID_index)
471 else if(lhs.
id() == ID_member)
473 else if(lhs.
id() == ID_symbol)
497void goto_check_ct::div_by_zero_check(
519void goto_check_ct::float_div_by_zero_check(
529 const notequal_exprt inequality(expr.
op1(), std::move(zero));
533 "floating-point division by zero",
534 "float-division-by-zero",
541void goto_check_ct::enum_range_check(
554 for(
const auto &d : pragmas)
556 if(d.first ==
"disable:enum-range-check")
560 const exprt check = enum_is_in_range_exprt{expr}.lower(
ns);
572void goto_check_ct::undefined_shift_check(
584 if(distance_type.
id() == ID_signedbv)
586 binary_relation_exprt inequality(
591 "shift distance is negative",
599 const typet &op_type = expr.
op().
type();
601 if(op_type.
id() == ID_unsignedbv || op_type.
id() == ID_signedbv)
607 binary_relation_exprt(expr.
distance(), ID_lt, std::move(width_expr)),
608 "shift distance too large",
615 if(op_type.
id() == ID_signedbv && expr.
id() == ID_shl)
617 binary_relation_exprt inequality(
622 "shift operand is negative",
634 "shift of non-integer type",
643void goto_check_ct::mod_by_zero_check(
653 const notequal_exprt inequality(expr.
divisor(), std::move(zero));
666void goto_check_ct::mod_overflow_check(
673 const auto &type = expr.
type();
675 if(type.id() == ID_signedbv)
682 notequal_exprt int_min_neq(
685 notequal_exprt minus_one_neq(
689 or_exprt(int_min_neq, minus_one_neq),
690 "result of signed mod is not representable",
707 if(type.
id() != ID_signedbv && type.
id() != ID_unsignedbv)
710 if(expr.
id() == ID_typecast)
715 const typet &old_type = op.type();
717 if(type.
id() == ID_signedbv)
721 if(old_type.
id() == ID_signedbv)
724 if(new_width >= old_width)
734 and_exprt(no_overflow_lower, no_overflow_upper),
735 "arithmetic overflow on signed type conversion",
742 else if(old_type.
id() == ID_unsignedbv)
745 if(new_width >= old_width + 1)
753 "arithmetic overflow on unsigned to signed type conversion",
760 else if(old_type.
id() == ID_floatbv)
775 and_exprt(no_overflow_lower, no_overflow_upper),
776 "arithmetic overflow on float to signed integer type conversion",
784 else if(type.
id() == ID_unsignedbv)
788 if(old_type.
id() == ID_signedbv)
792 if(new_width >= old_width - 1)
800 "arithmetic overflow on signed to unsigned type conversion",
817 and_exprt(no_overflow_lower, no_overflow_upper),
818 "arithmetic overflow on signed to unsigned type conversion",
826 else if(old_type.
id() == ID_unsignedbv)
829 if(new_width >= old_width)
837 "arithmetic overflow on unsigned to unsigned type conversion",
844 else if(old_type.
id() == ID_floatbv)
859 and_exprt(no_overflow_lower, no_overflow_upper),
860 "arithmetic overflow on float to unsigned integer type conversion",
889 if(expr.
id() == ID_div)
892 if(type.
id() == ID_signedbv)
903 "arithmetic overflow on signed division",
913 else if(expr.
id() == ID_unary_minus)
915 if(type.
id() == ID_signedbv)
925 "arithmetic overflow on signed unary minus",
932 else if(type.
id() == ID_unsignedbv)
942 "arithmetic overflow on unsigned unary minus",
952 else if(expr.
id() == ID_shl)
954 if(type.
id() == ID_signedbv)
957 const auto &op = shl_expr.op();
959 const auto op_width = op_type.get_width();
960 const auto &distance = shl_expr.distance();
961 const auto &distance_type = distance.type();
965 exprt neg_value_shift;
967 if(op_type.
id() == ID_unsignedbv)
975 exprt neg_dist_shift;
977 if(distance_type.
id() == ID_unsignedbv)
988 distance, ID_gt,
from_integer(op_width, distance_type));
993 new_type.set_width(op_width * 2);
1004 bool allow_shift_into_sign_bit =
true;
1012 allow_shift_into_sign_bit =
false;
1015 else if(
mode == ID_cpp)
1022 allow_shift_into_sign_bit =
false;
1026 const unsigned number_of_top_bits =
1027 allow_shift_into_sign_bit ? op_width : op_width + 1;
1031 new_type.get_width() - number_of_top_bits,
1034 const exprt top_bits_zero =
1049 "arithmetic overflow on signed shl",
1068 for(std::size_t i = 1; i < expr.
operands().size(); i++)
1080 std::string kind = type.
id() == ID_unsignedbv ?
"unsigned" :
"signed";
1084 "arithmetic overflow on " + kind +
" " + expr.
id_string(),
1092 else if(expr.
operands().size() == 2)
1094 std::string kind = type.
id() == ID_unsignedbv ?
"unsigned" :
"signed";
1099 "arithmetic overflow on " + kind +
" " + expr.
id_string(),
1110 std::string kind = type.
id() == ID_unsignedbv ?
"unsigned" :
"signed";
1114 "arithmetic overflow on " + kind +
" " + expr.
id_string(),
1131 if(type.
id() != ID_floatbv)
1136 if(expr.
id() == ID_typecast)
1141 if(op.type().id() == ID_floatbv)
1147 std::move(overflow_check),
1148 "arithmetic overflow on floating-point typecast",
1160 "arithmetic overflow on floating-point typecast",
1170 else if(expr.
id() == ID_div)
1177 std::move(overflow_check),
1178 "arithmetic overflow on floating-point division",
1187 else if(expr.
id() == ID_mod)
1192 else if(expr.
id() == ID_unary_minus)
1197 else if(expr.
id() == ID_plus || expr.
id() == ID_mult || expr.
id() == ID_minus)
1207 std::string kind = expr.
id() == ID_plus ?
"addition"
1208 : expr.
id() == ID_minus ?
"subtraction"
1209 : expr.
id() == ID_mult ?
"multiplication"
1213 std::move(overflow_check),
1214 "arithmetic overflow on floating-point " + kind,
1223 else if(expr.
operands().size() >= 3)
1240 if(expr.
type().
id() != ID_floatbv)
1244 expr.
id() != ID_plus && expr.
id() != ID_mult && expr.
id() != ID_div &&
1245 expr.
id() != ID_minus)
1252 if(expr.
id() == ID_div)
1261 div_expr.op0(),
from_integer(0, div_expr.dividend().type())),
1263 div_expr.op1(),
from_integer(0, div_expr.divisor().type())));
1267 isnan =
or_exprt(zero_div_zero, div_inf);
1269 else if(expr.
id() == ID_mult)
1280 mult_expr.op1(),
from_integer(0, mult_expr.op1().type())));
1284 mult_expr.op1(),
from_integer(0, mult_expr.op1().type())),
1287 isnan =
or_exprt(inf_times_zero, zero_times_inf);
1289 else if(expr.
id() == ID_plus)
1310 else if(expr.
id() == ID_minus)
1343void goto_check_ct::pointer_rel_check(
1360 "same object violation",
1367 for(
const auto &pointer : expr.
operands())
1374 for(
const auto &c : conditions)
1378 "pointer relation: " + c.description,
1379 "pointer arithmetic",
1389void goto_check_ct::pointer_overflow_check(
1396 if(expr.
id() != ID_plus && expr.
id() != ID_minus)
1401 "pointer arithmetic expected to have exactly 2 operands");
1406 if(object_type.
id() != ID_empty)
1413 exprt offset_operand = binary_expr.
lhs().
type().
id() == ID_pointer
1415 : binary_expr.
lhs();
1422 override_overflow.set_flag(
1424 override_overflow.set_flag(
1433 for(
const auto &c : conditions)
1437 "pointer arithmetic: " + c.description,
1438 "pointer arithmetic",
1448 const exprt &src_expr,
1458 if(expr.
type().
id() == ID_empty)
1470 size = size_of_expr_opt.value();
1475 for(
const auto &c : conditions)
1479 "dereference failure: " + c.description,
1480 "pointer dereference",
1498 const exprt pointer =
1499 (expr.
id() == ID_r_ok || expr.
id() == ID_w_ok || expr.
id() == ID_rw_ok)
1507 if(pointer.
id() == ID_symbol)
1517 for(
const auto &c : conditions)
1522 "pointer primitives",
1543 expr.
id() == ID_w_ok || expr.
id() == ID_rw_ok ||
1545 expr.
id() == ID_is_dynamic_object;
1548goto_check_ct::conditionst
1550 const exprt &address,
1557 conditions.push_front(*maybe_null_condition);
1564 return ::array_name(
ns, expr);
1572 if(expr.
id() == ID_index)
1575 (expr.
id() == ID_count_leading_zeros &&
1577 (expr.
id() == ID_count_trailing_zeros &&
1584void goto_check_ct::bounds_check_index(
1588 const typet &array_type = expr.
array().
type();
1590 if(array_type.
id() == ID_pointer)
1591 throw "index got pointer as array type";
1592 else if(array_type.
id() != ID_array && array_type.
id() != ID_vector)
1593 throw "bounds check expected array or vector type, got " +
1598 const exprt &index = expr.
index();
1599 object_descriptor_exprt ode;
1602 if(index.
type().
id() != ID_unsignedbv)
1606 index.
id() == ID_typecast &&
1615 if(!i.has_value() || *i < 0)
1617 exprt effective_offset = ode.
offset();
1624 effective_offset = plus_exprt{
1627 effective_offset, p_offset.
type())};
1633 binary_relation_exprt inequality(
1634 effective_offset, ID_ge, std::move(zero));
1638 name +
" lower bound",
1652 const plus_exprt effective_offset{
1657 binary_relation_exprt inequality{
1663 exprt in_bounds_of_some_explicit_allocation =
1669 std::move(in_bounds_of_some_explicit_allocation), inequality);
1673 name +
" dynamic object upper bound",
1683 const exprt &size = array_type.
id() == ID_array
1687 if(size.
is_nil() && !array_type.
get_bool(ID_C_flexible_array_member))
1692 else if(size.
id() == ID_infinity)
1696 expr.
array().
id() == ID_member &&
1697 (size == 0 || array_type.
get_bool(ID_C_flexible_array_member)))
1707 const auto type_size_opt =
1711 binary_relation_exprt inequality(
1718 name +
" upper bound",
1727 binary_relation_exprt inequality{
1732 name +
" upper bound",
1741void goto_check_ct::bounds_check_bit_count(
1747 if(expr.
id() == ID_count_leading_zeros)
1749 else if(expr.
id() == ID_count_trailing_zeros)
1756 "count " + name +
" zeros is undefined for value zero",
1765 const exprt &asserted_expr,
1767 const std::string &property_class,
1770 const exprt &src_expr,
1774 exprt simplified_expr =
1784 if(
assertions.insert(std::make_pair(src_expr, guarded_expr)).second)
1786 std::string source_expr_string;
1798 std::move(guarded_expr), annotated_location));
1806 std::move(guarded_expr), annotated_location));
1814 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
1817 if(expr.
id() == ID_dereference)
1821 else if(expr.
id() == ID_index)
1829 for(
const auto &operand : expr.
operands())
1837 expr.
id() == ID_and || expr.
id() == ID_or || expr.
id() == ID_implies);
1840 "'" + expr.
id_string() +
"' must be Boolean, but got " + expr.
pretty());
1844 for(
const auto &op : expr.
operands())
1848 "'" + expr.
id_string() +
"' takes Boolean operands only, but got " +
1851 auto new_guard = [&
guard, &constraints](
exprt expr) {
1865 "first argument of if must be boolean, but got " + if_expr.
cond().
pretty());
1870 auto new_guard = [&
guard, &if_expr](
exprt expr) {
1877 auto new_guard = [&
guard, &if_expr](
exprt expr) {
1884bool goto_check_ct::check_rec_member(
1901 if(member_offset_opt.has_value())
1916 dereference_exprt new_deref{new_address_casted};
1930 div_expr.
type().
id() == ID_signedbv ||
1931 div_expr.
type().
id() == ID_unsignedbv || div_expr.
type().
id() == ID_c_bool)
1936 else if(div_expr.
type().
id() == ID_floatbv)
1945 if(div_expr.
type().
id() == ID_signedbv)
1947 else if(div_expr.
type().
id() == ID_floatbv)
1958 if(expr.
type().
id() == ID_signedbv || expr.
type().
id() == ID_unsignedbv)
1963 expr.
operands().size() == 2 && expr.
id() == ID_minus &&
1964 expr.
operands()[0].type().id() == ID_pointer &&
1965 expr.
operands()[1].type().id() == ID_pointer)
1970 else if(expr.
type().
id() == ID_floatbv)
1975 else if(expr.
type().
id() == ID_pointer)
1977 pointer_overflow_check(expr,
guard);
1986 if(expr.
id() == ID_exists || expr.
id() == ID_forall)
1991 auto new_guard = [&
guard, &quantifier_expr](
exprt expr) {
1995 check_rec(quantifier_expr.where(), new_guard,
false);
1998 else if(expr.
id() == ID_address_of)
2003 else if(expr.
id() == ID_and || expr.
id() == ID_or || expr.
id() == ID_implies)
2008 else if(expr.
id() == ID_if)
2014 expr.
id() == ID_member &&
2021 for(
const auto &op : expr.
operands())
2024 if(expr.
type().
id() == ID_c_enum_tag)
2027 if(expr.
id() == ID_index)
2029 bounds_check(expr,
guard);
2031 else if(expr.
id() == ID_div)
2035 else if(expr.
id() == ID_shl || expr.
id() == ID_ashr || expr.
id() == ID_lshr)
2039 if(expr.
id() == ID_shl && expr.
type().
id() == ID_signedbv)
2042 else if(expr.
id() == ID_mod)
2048 expr.
id() == ID_plus || expr.
id() == ID_minus || expr.
id() == ID_mult ||
2049 expr.
id() == ID_unary_minus)
2053 else if(expr.
id() == ID_typecast)
2056 expr.
id() == ID_le || expr.
id() == ID_lt || expr.
id() == ID_ge ||
2059 else if(expr.
id() == ID_dereference)
2068 expr.
id() == ID_count_leading_zeros || expr.
id() == ID_count_trailing_zeros)
2070 bounds_check(expr,
guard);
2079void goto_check_ct::memory_leak_check(
const irep_idt &function_id)
2082 const symbol_exprt leak_expr = leak.
symbol_expr();
2087 source_locationt source_location;
2094 "dynamically allocated memory never freed",
2103 const irep_idt &function_identifier,
2106 const auto &function_symbol =
ns.lookup(function_identifier);
2107 mode = function_symbol.mode;
2114 bool did_something =
false;
2117 std::make_unique<local_bitvector_analysist>(goto_function,
ns);
2128 for(
const auto &d : pragmas)
2132 if(matched.has_value())
2134 auto named_check = matched.value();
2135 auto name = named_check.first;
2136 auto status = named_check.second;
2141 resetter.
set_flag(*flag,
true, name);
2144 resetter.
set_flag(*flag,
false, name);
2176 annotated_location.
set_comment(
"error label " + label);
2177 annotated_location.
set(
"user-provided",
true);
2195 const irep_idt &statement = code.get_statement();
2197 if(statement == ID_expression)
2201 else if(statement == ID_printf)
2203 for(
const auto &op : code.operands())
2212 check(assign_lhs,
true);
2213 check(assign_rhs,
false);
2248 (function_identifier ==
"abort" || function_identifier ==
"exit" ||
2249 function_identifier ==
"_Exit" ||
2250 (i.
labels.size() == 1 && i.
labels.front() ==
"__VERIFIER_abort")))
2252 memory_leak_check(function_identifier);
2270 std::move(address_of_expr),
2284 memory_leak_check(function_identifier);
2288 for(
auto &instruction :
new_code.instructions)
2290 if(instruction.source_location().is_nil())
2292 instruction.source_location_nonconst().id(
irep_idt());
2294 if(!it->source_location().get_file().empty())
2295 instruction.source_location_nonconst().set_file(
2296 it->source_location().get_file());
2298 if(!it->source_location().get_line().empty())
2299 instruction.source_location_nonconst().set_line(
2300 it->source_location().get_line());
2302 if(!it->source_location().get_function().empty())
2303 instruction.source_location_nonconst().set_function(
2304 it->source_location().get_function());
2306 if(!it->source_location().get_column().empty())
2308 instruction.source_location_nonconst().set_column(
2309 it->source_location().get_column());
2315 did_something |= !
new_code.instructions.empty();
2317 while(!
new_code.instructions.empty())
2347goto_check_ct::conditionst
2349 const exprt &address,
2357 conditionst conditions;
2359 const exprt in_bounds_of_some_explicit_allocation =
2366 conditions.push_back(conditiont{
2372 conditions.push_back(conditiont(
2374 in_bounds_of_some_explicit_allocation,
2376 "deallocated dynamic object"));
2381 conditions.push_back(conditiont(
2383 in_bounds_of_some_explicit_allocation,
2390 const or_exprt object_bounds_violation(
2394 conditions.push_back(conditiont(
2396 in_bounds_of_some_explicit_allocation,
2398 "pointer outside dynamic object bounds"));
2403 const or_exprt object_bounds_violation(
2407 conditions.push_back(conditiont(
2409 in_bounds_of_some_explicit_allocation,
2411 "pointer outside object bounds"));
2416 conditions.push_back(conditiont(
2419 "invalid integer address"));
2425std::optional<goto_check_ct::conditiont>
2427 const exprt &address,
2448 const exprt &pointer,
2462 std::move(upper_bound), ID_le,
plus_exprt{a.first, a.second}};
2464 alloc_disjuncts.push_back(
2465 and_exprt{std::move(lb_check), std::move(ub_check)});
2471 const irep_idt &function_identifier,
2478 goto_check.
goto_check(function_identifier, goto_function);
2493 goto_check.
goto_check(gf_entry.first, gf_entry.second);
2525 auto col = s.find(
":");
2527 if(col == std::string::npos)
2530 auto name = s.substr(col + 1);
2536 if(!s.compare(0, 6,
"enable"))
2538 else if(!s.compare(0, 7,
"disable"))
2540 else if(!s.compare(0, 7,
"checked"))
2546 return std::pair<irep_idt, check_statust>{name, status};
API to expression classes for bitvectors.
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
const shl_exprt & to_shl_expr(const exprt &expr)
Cast an exprt to a shl_exprt.
const count_leading_zeros_exprt & to_count_leading_zeros_expr(const exprt &expr)
Cast an exprt to a count_leading_zeros_exprt.
const count_trailing_zeros_exprt & to_count_trailing_zeros_expr(const exprt &expr)
Cast an exprt to a count_trailing_zeros_exprt.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
API to expression classes that are internal to the C frontend.
static exprt guard(const exprt::operandst &guards, exprt cond)
unsignedbv_typet size_type()
pointer_typet pointer_type(const typet &subtype)
signedbv_typet pointer_diff_type()
bitvector_typet char_type()
Operator to return the address of an object.
Boolean AND All operands must be boolean, and the result is always boolean.
const exprt & size() const
A base class for binary expressions.
A Boolean expression returning true, iff operation kind would result in an overflow when applied to o...
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly two argu...
A base class for relations, i.e., binary predicates whose two operands have the same type.
std::size_t get_width() const
A goto_instruction_codet representing an assignment in the program.
exprt::operandst argumentst
Operator to dereference a pointer.
Base class for all expressions.
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
std::vector< exprt > operandst
bool is_boolean() const
Return whether the expression represents a Boolean.
typet & type()
Return the type of the expression.
const source_locationt & source_location() const
source_locationt & add_source_location()
The Boolean constant false.
~flag_overridet()
Restore the values of all flags that have been modified via set_flag.
void disable_flag(bool &flag, const irep_idt &flag_name)
Sets the given flag to false, overriding any previous value.
void set_flag(bool &flag, bool new_value, const irep_idt &flag_name)
Store the current value of flag and then set its value to new_value.
std::map< bool *, bool > flags_to_reset
flag_overridet(const source_locationt &source_location)
std::set< bool * > disabled_flags
const source_locationt & source_location
named_check_statust match_named_check(const irep_idt &named_check) const
Matches a named-check string of the form.
void goto_check(const irep_idt &function_identifier, goto_functiont &goto_function)
void check_rec_logical_op(const exprt &expr, const guardt &guard)
Check a logical operation: check each operand in separation while extending the guarding condition as...
bool enable_float_div_by_zero_check
void check_rec_address(const exprt &expr, const guardt &guard)
Check an address-of expression: if it is a dereference then check the pointer if it is an index then ...
std::function< exprt(exprt)> guardt
std::string array_name(const exprt &)
void collect_allocations(const goto_functionst &goto_functions)
Fill the list of allocations allocationst with <address, size> for every allocation instruction.
bool enable_pointer_check
exprt is_in_bounds_of_some_explicit_allocation(const exprt &pointer, const exprt &size)
std::optional< goto_check_ct::conditiont > get_pointer_is_null_condition(const exprt &address, const exprt &size)
void invalidate(const exprt &lhs)
Remove all assertions containing the symbol in lhs as well as all assertions containing dereference.
check_statust
activation statuses for named checks
void float_overflow_check(const exprt &, const guardt &)
bool enable_pointer_primitive_check
bool requires_pointer_primitive_check(const exprt &expr)
Returns true if the given expression is a pointer primitive that requires validation of the operand t...
std::map< irep_idt, bool * > name_to_flag
Maps a named-check name to the corresponding boolean flag.
bool enable_float_overflow_check
bool enable_conversion_check
void check_rec_div(const div_exprt &div_expr, const guardt &guard)
Check that a member expression is valid:
bool enable_pointer_overflow_check
void pointer_primitive_check(const exprt &expr, const guardt &guard)
Generates VCCs to check that pointers passed to pointer primitives are either null or valid.
bool enable_signed_overflow_check
conditionst get_pointer_dereferenceable_conditions(const exprt &address, const exprt &size)
void check_rec(const exprt &expr, const guardt &guard, bool is_assigned)
Recursively descend into expr and run the appropriate check for each sub-expression,...
goto_functionst::goto_functiont goto_functiont
std::optional< std::pair< irep_idt, check_statust > > named_check_statust
optional (named-check, status) pair
std::pair< exprt, exprt > allocationt
bool enable_memory_leak_check
void add_guarded_property(const exprt &asserted_expr, const std::string &comment, const std::string &property_class, bool is_fatal, const source_locationt &source_location, const exprt &src_expr, const guardt &guard)
Include the asserted_expr in the code conditioned by the guard.
void conversion_check(const exprt &, const guardt &)
void check_rec_if(const if_exprt &if_expr, const guardt &guard)
Check an if expression: check the if-condition alone, and then check the true/false-cases with the gu...
void integer_overflow_check(const exprt &, const guardt &)
bool enable_assert_to_assume
bool enable_memory_cleanup_check
void nan_check(const exprt &, const guardt &)
bool enable_undefined_shift_check
std::list< allocationt > allocationst
bool enable_enum_range_check
goto_programt::const_targett current_target
void add_all_checked_named_check_pragmas(source_locationt &source_location) const
Adds "checked" pragmas for all named checks on the given source location (prevents any the instanciat...
optionst::value_listt error_labelst
void add_active_named_check_pragmas(source_locationt &source_location) const
Adds "checked" pragmas for all currently active named checks on the given source location.
goto_check_ct(const namespacet &_ns, const optionst &_options, message_handlert &_message_handler)
conditionst get_pointer_points_to_valid_memory_conditions(const exprt &address, const exprt &size)
bool enable_unsigned_overflow_check
bool enable_div_by_zero_check
void check_shadow_memory_api_calls(const goto_programt::instructiont &)
error_labelst error_labels
void check_rec_arithmetic_op(const exprt &expr, const guardt &guard)
Check that an arithmetic operation is valid: overflow check, NaN-check (for floating point numbers),...
std::unique_ptr< local_bitvector_analysist > local_bitvector_analysis
std::set< std::pair< exprt, exprt > > assertionst
void pointer_validity_check(const dereference_exprt &expr, const exprt &src_expr, const guardt &guard)
Initiate the recursively analysis of expr with its `guard' set to TRUE.
A collection of goto functions.
function_mapt function_map
::goto_functiont goto_functiont
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
symbol_tablet symbol_table
Symbol table.
goto_functionst goto_functions
GOTO functions.
This class represents an instruction in the GOTO intermediate representation.
const symbol_exprt & dead_symbol() const
Get the symbol for DEAD.
bool is_end_function() const
const exprt & call_lhs() const
Get the lhs of a FUNCTION_CALL (may be nil).
const goto_instruction_codet & get_other() const
Get the statement for OTHER.
bool is_target() const
Is this node a branch target?
const exprt & return_value() const
Get the return value of a SET_RETURN_VALUE instruction.
bool is_set_return_value() const
bool has_condition() const
Does this instruction have a condition?
const exprt::operandst & call_arguments() const
Get the arguments of a FUNCTION_CALL.
const exprt & assign_lhs() const
Get the lhs of the assignment for ASSIGN.
const exprt & assign_rhs() const
Get the rhs of the assignment for ASSIGN.
const exprt & call_function() const
Get the function that is called for FUNCTION_CALL.
bool is_function_call() const
const exprt & condition() const
Get the condition of gotos, assume, assert.
source_locationt & source_location_nonconst()
const source_locationt & source_location() const
A generic container class for the GOTO intermediate representation of one function.
static instructiont make_assumption(const exprt &g, const source_locationt &l=source_locationt::nil())
void insert_before_swap(targett target)
Insertion that preserves jumps to "target".
instructionst::const_iterator const_targett
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
static instructiont make_assertion(const exprt &g, const source_locationt &l=source_locationt::nil())
IEEE-floating-point equality.
static ieee_float_valuet minus_infinity(const ieee_float_spect &_spec)
constant_exprt to_expr() const
static ieee_float_valuet plus_infinity(const ieee_float_spect &_spec)
An IEEE 754 value plus a rounding mode, enabling operations with rounding on values.
void from_integer(const mp_integer &i)
The trinary if-then-else operator.
bool get_bool(const irep_idt &name) const
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
void set(const irep_idt &name, const irep_idt &value)
const std::string & id_string() const
const irep_idt & id() const
Evaluates to true if the operand is infinite.
virtual bool from_expr(const exprt &expr, std::string &code, const namespacet &ns)
Formats the given expression in a language-specific way.
Extract member of struct or union.
const exprt & struct_op() const
Class that provides messages with a built-in verbosity 'level'.
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
exprt & divisor()
The divisor of a division is the number the dividend is being divided by.
A base class for multi-ary expressions Associativity is not specified.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
void build(const exprt &expr, const namespacet &ns)
Given an expression expr, attempt to find the underlying object it represents by skipping over type c...
static const exprt & root_object(const exprt &expr)
bool get_bool_option(const std::string &option) const
const value_listt & get_list_option(const std::string &option) const
std::list< std::string > value_listt
Boolean OR All operands must be boolean, and the result is always boolean.
The plus expression Associativity is not specified.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
const exprt & pointer() const
const exprt & pointer() const
A base class for shift and rotate operators.
A side_effect_exprt that returns a non-deterministically chosen value.
void set_comment(const irep_idt &comment)
bool property_fatal() const
void set_property_class(const irep_idt &property_class)
void add_pragma(const irep_idt &pragma)
const irept::named_subt & get_pragmas() const
static bool is_built_in(const std::string &s)
void set_function(const irep_idt &function)
Expression to hold a symbol (variable).
void identifier(const irep_idt &identifier)
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
Semantic type conversion.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
Generic base class for unary expressions.
A Boolean expression returning true, iff negation would result in an overflow when applied to the (si...
Fixed-width bit-vector with unsigned binary interpretation.
const constant_exprt & size() const
static bool is_assigned(dirtyt &dirty, const irep_idt &ident, assignst assigns)
exprt make_binary(const exprt &expr)
splits an expression with >=3 operands into nested binary expressions
bool has_subexpr(const exprt &expr, const std::function< bool(const exprt &)> &pred)
returns true if the expression has a subexpression that satisfies pred
exprt boolean_negate(const exprt &src)
negate a Boolean expression, possibly removing a not_exprt, and swapping false and true
Deprecated expression utility functions.
bool has_symbol_expr(const exprt &src, const irep_idt &identifier, bool include_bound_symbols)
Returns true if one of the symbol expressions in src has identifier identifier; if include_bound_symb...
API to expression classes for floating-point arithmetic.
void goto_check_c(const irep_idt &function_identifier, goto_functionst::goto_functiont &goto_function, const namespacet &ns, const optionst &options, message_handlert &message_handler)
static exprt implication(exprt lhs, exprt rhs)
#define Forall_goto_program_instructions(it, program)
const std::string & id2string(const irep_idt &d)
Abstract interface to support a programming language.
Field-insensitive, location-sensitive bitvector analysis.
API to expression classes for 'mathematical' expressions.
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
std::unique_ptr< languaget > get_language_from_mode(const irep_idt &mode)
Get the language corresponding to the given mode.
API to expression classes for Pointers.
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
bool can_cast_expr< object_size_exprt >(const exprt &base)
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
const prophecy_r_or_w_ok_exprt & to_prophecy_r_or_w_ok_expr(const exprt &expr)
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
bool can_cast_expr< prophecy_r_or_w_ok_exprt >(const exprt &base)
std::optional< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
std::optional< exprt > member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
exprt pointer_offset(const exprt &pointer)
exprt integer_address(const exprt &pointer)
exprt deallocated(const exprt &pointer, const namespacet &ns)
exprt object_size(const exprt &pointer)
exprt object_upper_bound(const exprt &pointer, const exprt &access_size)
exprt dead_object(const exprt &pointer, const namespacet &ns)
exprt same_object(const exprt &p1, const exprt &p2)
exprt null_object(const exprt &pointer)
exprt object_lower_bound(const exprt &pointer, const exprt &offset)
Various predicates over pointers in programs.
static std::string comment(const rw_set_baset::entryt &entry, bool write)
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
exprt simplify_expr(exprt src, const namespacet &ns)
#define CHECK_RETURN(CONDITION)
#define UNREACHABLE
This should be used to mark dead code.
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
exprt disjunction(const exprt::operandst &op)
1) generates a disjunction for two or more operands 2) for one operand, returns the operand 3) return...
exprt conjunction(exprt a, exprt b)
Conjunction of two expressions.
API to expression classes.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const mod_exprt & to_mod_expr(const exprt &expr)
Cast an exprt to a mod_exprt.
const mult_exprt & to_mult_expr(const exprt &expr)
Cast an exprt to a mult_exprt.
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const div_exprt & to_div_expr(const exprt &expr)
Cast an exprt to a div_exprt.
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
const minus_exprt & to_minus_expr(const exprt &expr)
Cast an exprt to a minus_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
const unary_minus_exprt & to_unary_minus_expr(const exprt &expr)
Cast an exprt to a unary_minus_exprt.
const vector_typet & to_vector_type(const typet &type)
Cast a typet to a vector_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
bool is_static_lifetime() const
bool is_dynamic_local() const
bool is_dynamic_heap() const
bool is_uninitialized() const
bool is_integer_address() const