Skip to content

Commit 2888ad3

Browse files
committed
SMT back-end: report too-many-addressed-objects
Fail generation of the SMT encoding with a meaningful error message rather than generating invalid SMT-LIB output. The behaviour now matches that of the SAT back-end. Fixes: #7623
1 parent b34e991 commit 2888ad3

File tree

4 files changed

+33
-32
lines changed

4 files changed

+33
-32
lines changed

regression/cbmc/address_space_size_limit1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE thorough-paths broken-smt-backend
1+
CORE thorough-paths
22
test.c
33
--no-simplify --unwind 300 --object-bits 8
44
too many addressed objects

src/solvers/smt2/smt2_conv.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -782,12 +782,21 @@ void smt2_convt::convert_address_of_rec(
782782
expr.id() == ID_symbol || expr.is_constant() ||
783783
expr.id() == ID_string_constant || expr.id() == ID_label)
784784
{
785-
out
786-
<< "(concat (_ bv"
787-
<< pointer_logic.add_object(expr) << " "
788-
<< config.bv_encoding.object_bits << ")"
789-
<< " (_ bv0 "
790-
<< boolbv_width(result_type)-config.bv_encoding.object_bits << "))";
785+
const std::size_t object_bits = config.bv_encoding.object_bits;
786+
const std::size_t max_objects = std::size_t(1) << object_bits;
787+
const mp_integer object_id = pointer_logic.add_object(expr);
788+
789+
if(object_id >= max_objects)
790+
{
791+
throw analysis_exceptiont{
792+
"too many addressed objects: maximum number of objects is set to 2^n=" +
793+
std::to_string(max_objects) +
794+
" (with n=" + std::to_string(object_bits) + "); " +
795+
"use the `--object-bits n` option to increase the maximum number"};
796+
}
797+
798+
out << "(concat (_ bv" << object_id << " " << object_bits << ")"
799+
<< " (_ bv0 " << boolbv_width(result_type) - object_bits << "))";
791800
}
792801
else if(expr.id()==ID_index)
793802
{

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -854,15 +854,6 @@ static smt_termt convert_expr_to_smt(
854854
}
855855
}
856856

857-
#ifndef CPROVER_INVARIANT_DO_NOT_CHECK
858-
static mp_integer power2(unsigned exponent)
859-
{
860-
mp_integer result;
861-
result.setPower2(exponent);
862-
return result;
863-
}
864-
#endif
865-
866857
/// \details
867858
/// This conversion constructs a bit vector representation of the memory
868859
/// address. This address is composed of 2 concatenated bit vector components.
@@ -884,16 +875,23 @@ static smt_termt convert_expr_to_smt(
884875
object != object_map.end(),
885876
"Objects should be tracked before converting their address to SMT terms");
886877
const std::size_t object_id = object->second.unique_id;
887-
INVARIANT(
888-
object_id < power2(config.bv_encoding.object_bits),
889-
"There should be sufficient bits to encode unique object identifier.");
878+
const std::size_t object_bits = config.bv_encoding.object_bits;
879+
const std::size_t max_objects = std::size_t(1) << object_bits;
880+
if(object_id >= max_objects)
881+
{
882+
throw analysis_exceptiont{
883+
"too many addressed objects: maximum number of objects is set to 2^n=" +
884+
std::to_string(max_objects) + " (with n=" + std::to_string(object_bits) +
885+
"); " +
886+
"use the `--object-bits n` option to increase the maximum number"};
887+
}
890888
const smt_termt object_bit_vector =
891-
smt_bit_vector_constant_termt{object_id, config.bv_encoding.object_bits};
889+
smt_bit_vector_constant_termt{object_id, object_bits};
892890
INVARIANT(
893-
type->get_width() > config.bv_encoding.object_bits,
891+
type->get_width() > object_bits,
894892
"Pointer should be wider than object_bits in order to allow for offset "
895893
"encoding.");
896-
const size_t offset_bits = type->get_width() - config.bv_encoding.object_bits;
894+
const size_t offset_bits = type->get_width() - object_bits;
897895
if(
898896
const auto symbol =
899897
expr_try_dynamic_cast<symbol_exprt>(address_of.object()))

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,23 +1525,17 @@ TEST_CASE(
15251525
const address_of_exprt address_of_foo{foo};
15261526
track_expression_objects(address_of_foo, ns, test.object_map);
15271527
test.object_map.at(foo).unique_id = 256;
1528-
REQUIRE_THROWS_MATCHES(
1529-
test.convert(address_of_exprt{foo}),
1530-
invariant_failedt,
1531-
invariant_failure_containing("There should be sufficient bits to "
1532-
"encode unique object identifier."));
1528+
REQUIRE_THROWS_AS(
1529+
test.convert(address_of_exprt{foo}), analysis_exceptiont);
15331530
}
15341531
SECTION("Pointer should be wide enough to encode offset")
15351532
{
15361533
config.bv_encoding.object_bits = 64;
15371534
const address_of_exprt address_of_foo{foo};
15381535
track_expression_objects(address_of_foo, ns, test.object_map);
15391536
test.object_map.at(foo).unique_id = 256;
1540-
REQUIRE_THROWS_MATCHES(
1541-
test.convert(address_of_exprt{foo}),
1542-
invariant_failedt,
1543-
invariant_failure_containing("Pointer should be wider than object_bits "
1544-
"in order to allow for offset encoding."));
1537+
REQUIRE_THROWS_AS(
1538+
test.convert(address_of_exprt{foo}), analysis_exceptiont);
15451539
}
15461540
}
15471541
SECTION("Comparison of address of operations.")

0 commit comments

Comments
 (0)