Skip to content

Commit 185c77f

Browse files
committed
Introduce bitst and bytest to avoid bit/byte mix-up
Use mp_integers with a unit to clarify when an mp_integer holds a number of bits or a number of bytes. This makes sure that type-inconsistent comparisons as fixed in #7411 result in compile-time errors.
1 parent 9904695 commit 185c77f

29 files changed

+427
-265
lines changed

src/ansi-c/padding.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ static void add_padding_msvc(struct_typet &type, const namespacet &ns)
251251
{
252252
// keep track of offset
253253
const auto size = pointer_offset_size(it->type(), ns);
254-
if(size.has_value() && *size >= 1)
254+
if(size.has_value() && *size >= bytest{1})
255255
offset += *size;
256256
}
257257
}
@@ -468,7 +468,7 @@ void add_padding(union_typet &type, const namespacet &ns)
468468
{
469469
mp_integer max_alignment_bits =
470470
alignment(type, ns) * config.ansi_c.char_width;
471-
mp_integer size_bits=0;
471+
bitst size_bits{0};
472472

473473
// check per component, and ignore those without fixed size
474474
for(const auto &c : type.components())

src/cprover/bv_pointers_wide.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ optionalt<bvt> bv_pointers_widet::convert_address_of_rec(const exprt &expr)
209209

210210
// get size
211211
auto size = pointer_offset_size(array_type.element_type(), ns);
212-
CHECK_RETURN(size.has_value() && *size >= 0);
212+
CHECK_RETURN(size.has_value() && *size >= bytest{0});
213213

214214
bv = offset_arithmetic(type, bv, *size, index);
215215
CHECK_RETURN(bv.size() == bits);
@@ -424,7 +424,7 @@ bvt bv_pointers_widet::convert_pointer_type(const exprt &expr)
424424
else
425425
{
426426
auto size_opt = pointer_offset_size(pointer_base_type, ns);
427-
CHECK_RETURN(size_opt.has_value() && *size_opt >= 0);
427+
CHECK_RETURN(size_opt.has_value() && *size_opt >= bytest{0});
428428
size = *size_opt;
429429
}
430430
}
@@ -495,7 +495,8 @@ bvt bv_pointers_widet::convert_pointer_type(const exprt &expr)
495495
else
496496
{
497497
auto element_size_opt = pointer_offset_size(pointer_base_type, ns);
498-
CHECK_RETURN(element_size_opt.has_value() && *element_size_opt > 0);
498+
CHECK_RETURN(
499+
element_size_opt.has_value() && *element_size_opt > bytest{0});
499500
element_size = *element_size_opt;
500501
}
501502

@@ -550,7 +551,7 @@ bvt bv_pointers_widet::convert_pointer_type(const exprt &expr)
550551

551552
// get element size
552553
auto size = pointer_offset_size(element_address_expr.element_type(), ns);
553-
CHECK_RETURN(size.has_value() && *size >= 0);
554+
CHECK_RETURN(size.has_value() && *size >= bytest{0});
554555

555556
// add offset
556557
bv = offset_arithmetic(
@@ -637,9 +638,10 @@ bvt bv_pointers_widet::convert_bitvector(const exprt &expr)
637638
if(lhs_pt.base_type().id() != ID_empty)
638639
{
639640
auto element_size_opt = pointer_offset_size(lhs_pt.base_type(), ns);
640-
CHECK_RETURN(element_size_opt.has_value() && *element_size_opt > 0);
641+
CHECK_RETURN(
642+
element_size_opt.has_value() && *element_size_opt > bytest{0});
641643

642-
if(*element_size_opt != 1)
644+
if(*element_size_opt != bytest{1})
643645
{
644646
bvt element_size_bv =
645647
bv_utils.build_constant(*element_size_opt, width);
@@ -790,7 +792,7 @@ exprt bv_pointers_widet::bv_get_rec(
790792

791793
pointer_logict::pointert pointer{
792794
numeric_cast_v<std::size_t>(binary2integer(value_addr, false)),
793-
binary2integer(value_offset, true)};
795+
bytest{binary2integer(value_offset, true)}};
794796

795797
return annotated_pointer_constant_exprt{
796798
bvrep, pointer_logic.pointer_expr(pointer, pt)};

src/cprover/endianness_map_wide.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void endianness_map_widet::build_little_endian(const typet &src)
1818
{
1919
auto s = pointer_offset_bits(src, ns);
2020
CHECK_RETURN(s.has_value());
21-
s.value() = s.value() * 2;
21+
s.value() = bitst{s.value() * 2};
2222

2323
const std::size_t new_size = map.size() + numeric_cast_v<std::size_t>(*s);
2424
map.reserve(new_size);

src/goto-instrument/count_eloc.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ void print_global_state_size(const goto_modelt &goto_model)
185185
}
186186
}
187187

188-
mp_integer total_size = 0;
188+
bitst total_size{0};
189189

190190
for(const auto &symbol_entry : goto_model.symbol_table.symbols)
191191
{
@@ -200,7 +200,7 @@ void print_global_state_size(const goto_modelt &goto_model)
200200
}
201201

202202
const auto bits = pointer_offset_bits(symbol.type, ns);
203-
if(bits.has_value() && bits.value() > 0)
203+
if(bits.has_value() && bits.value() > bitst{0})
204204
total_size += bits.value();
205205
}
206206

src/goto-programs/interpreter_class.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ class interpretert
287287

288288
bool byte_offset_to_memory_offset(
289289
const typet &source_type,
290-
const mp_integer &byte_offset,
290+
const bytest &byte_offset,
291291
mp_integer &result);
292292

293293
bool memory_offset_to_byte_offset(

src/goto-programs/interpreter_evaluate.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ bool interpretert::count_type_leaves(const typet &ty, mp_integer &result)
159159
/// \return Offset into a vector of interpreter values; returns true on error
160160
bool interpretert::byte_offset_to_memory_offset(
161161
const typet &source_type,
162-
const mp_integer &offset,
162+
const bytest &offset,
163163
mp_integer &result)
164164
{
165165
if(source_type.id()==ID_struct)
@@ -206,7 +206,7 @@ bool interpretert::byte_offset_to_memory_offset(
206206

207207
mp_integer array_size=array_size_vec[0];
208208
auto elem_size_bytes = pointer_offset_size(at.element_type(), ns);
209-
if(!elem_size_bytes.has_value() || *elem_size_bytes == 0)
209+
if(!elem_size_bytes.has_value() || *elem_size_bytes == bytest{0})
210210
return true;
211211

212212
mp_integer elem_size_leaves;
@@ -228,7 +228,7 @@ bool interpretert::byte_offset_to_memory_offset(
228228
{
229229
result=0;
230230
// Can't currently subdivide a primitive.
231-
return offset!=0;
231+
return offset != bytest{0};
232232
}
233233
}
234234

@@ -1071,7 +1071,9 @@ mp_integer interpretert::evaluate_address(
10711071
{
10721072
mp_integer memory_offset;
10731073
if(!byte_offset_to_memory_offset(
1074-
byte_extract_expr.op0().type(), extract_offset[0], memory_offset))
1074+
byte_extract_expr.op0().type(),
1075+
bytest{extract_offset[0]},
1076+
memory_offset))
10751077
return evaluate_address(byte_extract_expr.op0(), fail_quietly) +
10761078
memory_offset;
10771079
}

src/goto-programs/vcd_goto_trace.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void output_vcd(
100100

101101
const auto width = pointer_offset_bits(type, ns);
102102

103-
if(width.has_value() && (*width) >= 1)
103+
if(width.has_value() && (*width) >= bitst{1})
104104
out << "$var reg " << (*width) << " V" << number << " " << identifier
105105
<< " $end"
106106
<< "\n";

src/goto-symex/symex_builtin_functions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ void goto_symext::symex_allocate(
8383
{
8484
// Did the size get multiplied?
8585
auto elem_size = pointer_offset_size(*tmp_type, ns);
86-
const auto alloc_size = numeric_cast<mp_integer>(tmp_size);
86+
const auto alloc_size = numeric_cast<bytest>(tmp_size);
8787

88-
if(!elem_size.has_value() || *elem_size==0)
88+
if(!elem_size.has_value() || *elem_size == bytest{0})
8989
{
9090
}
9191
else if(

src/memory-analyzer/analyze_symbol.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ exprt gdb_value_extractort::get_pointer_to_member_value(
325325

326326
const auto maybe_member_expr = get_subexpression_at_offset(
327327
struct_symbol_expr,
328-
member_offset,
328+
bytest{member_offset},
329329
to_pointer_type(expr.type()).base_type(),
330330
ns);
331331
DATA_INVARIANT(
@@ -554,7 +554,10 @@ exprt gdb_value_extractort::get_pointer_value(
554554
if(target_expr.type().id() == ID_array)
555555
{
556556
const auto result_indexed_expr = get_subexpression_at_offset(
557-
target_expr, 0, to_pointer_type(zero_expr.type()).base_type(), ns);
557+
target_expr,
558+
bytest{0},
559+
to_pointer_type(zero_expr.type()).base_type(),
560+
ns);
558561
CHECK_RETURN(result_indexed_expr.has_value());
559562
if(result_indexed_expr->type() == zero_expr.type())
560563
return *result_indexed_expr;

src/pointer-analysis/value_set.cpp

+13-13
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ bool value_sett::eval_pointer_offset(
314314
get_value_set(to_pointer_offset_expr(expr).pointer(), ns, true);
315315

316316
exprt new_expr;
317-
mp_integer previous_offset=0;
317+
bytest previous_offset{0};
318318

319319
const object_map_dt &object_map=reference_set.read();
320320
for(object_map_dt::const_iterator
@@ -568,7 +568,7 @@ void value_sett::get_value_set_rec(
568568
insert(
569569
dest,
570570
exprt(ID_null_object, to_pointer_type(expr_type).base_type()),
571-
mp_integer{0});
571+
bytest{0});
572572
}
573573
else if(expr_type.id()==ID_unsignedbv ||
574574
expr_type.id()==ID_signedbv)
@@ -599,7 +599,7 @@ void value_sett::get_value_set_rec(
599599

600600
if(op.is_zero())
601601
{
602-
insert(dest, exprt(ID_null_object, empty_typet{}), mp_integer{0});
602+
insert(dest, exprt(ID_null_object, empty_typet{}), bytest{0});
603603
}
604604
else
605605
{
@@ -686,7 +686,7 @@ void value_sett::get_value_set_rec(
686686

687687
auto size = pointer_offset_size(pointer_base_type, ns);
688688

689-
if(!size.has_value() || (*size) == 0)
689+
if(!size.has_value() || (*size) == bytest{0})
690690
{
691691
i.reset();
692692
}
@@ -728,7 +728,7 @@ void value_sett::get_value_set_rec(
728728

729729
// adjust by offset
730730
if(offset && i.has_value())
731-
*offset += *i;
731+
*offset += bytest{*i};
732732
else
733733
offset.reset();
734734

@@ -802,7 +802,7 @@ void value_sett::get_value_set_rec(
802802
dynamic_object.set_instance(location_number);
803803
dynamic_object.valid()=true_exprt();
804804

805-
insert(dest, dynamic_object, mp_integer{0});
805+
insert(dest, dynamic_object, bytest{0});
806806
}
807807
else if(statement==ID_cpp_new ||
808808
statement==ID_cpp_new_array)
@@ -815,7 +815,7 @@ void value_sett::get_value_set_rec(
815815
dynamic_object.set_instance(location_number);
816816
dynamic_object.valid()=true_exprt();
817817

818-
insert(dest, dynamic_object, mp_integer{0});
818+
insert(dest, dynamic_object, bytest{0});
819819
}
820820
else
821821
insert(dest, exprt(ID_unknown, original_type));
@@ -1146,7 +1146,7 @@ void value_sett::get_reference_set_rec(
11461146
to_array_type(expr.type()).element_type().id() == ID_array)
11471147
insert(dest, expr);
11481148
else
1149-
insert(dest, expr, mp_integer{0});
1149+
insert(dest, expr, bytest{0});
11501150

11511151
return;
11521152
}
@@ -1173,7 +1173,7 @@ void value_sett::get_reference_set_rec(
11731173

11741174
const index_exprt &index_expr=to_index_expr(expr);
11751175
const exprt &array=index_expr.array();
1176-
const exprt &offset=index_expr.index();
1176+
const exprt &index = index_expr.index();
11771177

11781178
DATA_INVARIANT(
11791179
array.type().id() == ID_array, "index takes array-typed operand");
@@ -1201,19 +1201,19 @@ void value_sett::get_reference_set_rec(
12011201
from_integer(0, c_index_type()));
12021202

12031203
offsett o = a_it->second;
1204-
const auto i = numeric_cast<mp_integer>(offset);
1204+
const auto i = numeric_cast<mp_integer>(index);
12051205

1206-
if(offset.is_zero())
1206+
if(index.is_zero())
12071207
{
12081208
}
12091209
else if(i.has_value() && o)
12101210
{
12111211
auto size = pointer_offset_size(array_type.element_type(), ns);
12121212

1213-
if(!size.has_value() || *size == 0)
1213+
if(!size.has_value() || *size == bytest{0})
12141214
o.reset();
12151215
else
1216-
*o = *i * (*size);
1216+
*o = bytest{*i * (*size)};
12171217
}
12181218
else
12191219
o.reset();

src/pointer-analysis/value_set.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class value_sett
7777

7878
/// Represents the offset into an object: either a unique integer offset,
7979
/// or an unknown value, represented by `!offset`.
80-
typedef optionalt<mp_integer> offsett;
80+
typedef optionalt<bytest> offsett;
8181

8282
/// Represents a set of expressions (`exprt` instances) with corresponding
8383
/// offsets (`offsett` instances). This is the RHS set of a single row of
@@ -145,10 +145,8 @@ class value_sett
145145
/// \param dest: object map to update
146146
/// \param src: expression to add
147147
/// \param offset_value: offset into `src`
148-
bool insert(
149-
object_mapt &dest,
150-
const exprt &src,
151-
const mp_integer &offset_value) const
148+
bool
149+
insert(object_mapt &dest, const exprt &src, const bytest &offset_value) const
152150
{
153151
return insert(dest, object_numbering.number(src), offsett(offset_value));
154152
}

src/pointer-analysis/value_set_dereference.cpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -613,12 +613,11 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
613613
auto element_size =
614614
pointer_offset_size(to_array_type(root_object_type).element_type(), ns);
615615
CHECK_RETURN(element_size.has_value());
616-
CHECK_RETURN(*element_size > 0);
616+
CHECK_RETURN(*element_size > bytest{0});
617617

618-
const auto offset_int =
619-
numeric_cast_v<mp_integer>(to_constant_expr(offset));
618+
const auto offset_int = numeric_cast_v<bytest>(to_constant_expr(offset));
620619

621-
if(offset_int % *element_size == 0)
620+
if(offset_int % *element_size == bytest{0})
622621
{
623622
index_exprt index_expr{
624623
root_object,
@@ -755,14 +754,14 @@ bool value_set_dereferencet::memory_model_bytes(
755754
auto from_type_element_type_size =
756755
from_type.id() == ID_array
757756
? pointer_offset_size(to_array_type(from_type).element_type(), ns)
758-
: optionalt<mp_integer>{};
757+
: optionalt<bytest>{};
759758

760759
auto to_type_size = pointer_offset_size(to_type, ns);
761760

762761
if(
763762
from_type.id() == ID_array && from_type_element_type_size.has_value() &&
764-
*from_type_element_type_size == 1 && to_type_size.has_value() &&
765-
*to_type_size == 1 &&
763+
*from_type_element_type_size == bytest{1} && to_type_size.has_value() &&
764+
*to_type_size == bytest{1} &&
766765
is_a_bv_type(to_array_type(from_type).element_type()) &&
767766
is_a_bv_type(to_type))
768767
{

0 commit comments

Comments
 (0)