Skip to content

Commit 9ab636f

Browse files
committed
Do not hardcode char/bytes having 8 bits
The C standard does not guarantee that char is exactly 8 bits, and there are DSPs (such Texas Instruments C55x) that do not have 8-bit-bytes. Use the configuration value instead.
1 parent 98f8c57 commit 9ab636f

File tree

8 files changed

+73
-54
lines changed

8 files changed

+73
-54
lines changed

src/cprover/cprover_parse_options.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,9 @@ void cprover_parse_optionst::help()
308308
{
309309
std::cout << '\n';
310310

311-
std::cout
312-
<< u8"* * CPROVER " << CBMC_VERSION << " (" << (sizeof(void *) * 8)
313-
<< "-bit)"
314-
<< " * *\n"
315-
<< "* * Copyright 2022 * *\n";
311+
std::cout << '\n'
312+
<< banner_string("CPROVER", CBMC_VERSION) << '\n'
313+
<< align_center_with_border("Copyright 2022") << '\n';
316314

317315
// clang-format off
318316
std::cout << help_formatter(

src/goto-instrument/contracts/memory_predicates.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void is_fresh_baset::update_ensures(goto_programt &ensures)
137137

138138
array_typet is_fresh_baset::get_memmap_type()
139139
{
140-
return array_typet(c_bool_typet(8), infinity_exprt(size_type()));
140+
return array_typet(unsigned_char_type(), infinity_exprt(size_type()));
141141
}
142142

143143
void is_fresh_baset::add_memory_map_decl(goto_programt &program)
@@ -149,7 +149,8 @@ void is_fresh_baset::add_memory_map_decl(goto_programt &program)
149149
goto_programt::make_decl(memmap_symbol.symbol_expr(), source_location));
150150
program.add(goto_programt::make_assignment(
151151
memmap_symbol.symbol_expr(),
152-
array_of_exprt(from_integer(0, c_bool_typet(8)), get_memmap_type()),
152+
array_of_exprt(
153+
from_integer(0, get_memmap_type().element_type()), get_memmap_type()),
153154
source_location));
154155
}
155156

src/goto-instrument/stack_depth.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Date: November 2011
1515

1616
#include <util/arith_tools.h>
1717
#include <util/bitvector_types.h>
18+
#include <util/c_types.h>
1819

1920
#include <goto-programs/goto_convert_functions.h>
2021
#include <goto-programs/goto_model.h>
@@ -26,7 +27,7 @@ static symbol_exprt add_stack_depth_symbol(
2627
message_handlert &message_handler)
2728
{
2829
const irep_idt identifier="$stack_depth";
29-
unsignedbv_typet type(sizeof(std::size_t)*8);
30+
typet type = size_type();
3031

3132
symbolt new_symbol;
3233
new_symbol.name=identifier;

src/goto-instrument/synthesizer/expr_enumerator.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Author: Qinheping Hu
88
#include <util/format_expr.h>
99
#include <util/simplify_expr.h>
1010

11+
#include <climits>
12+
1113
expr_sett leaf_enumeratort::enumerate(const std::size_t size) const
1214
{
1315
// Size of leaf expressions must be 1.
@@ -185,7 +187,7 @@ get_partitions_long(const std::size_t n, const std::size_t k)
185187
/// Compute all positions of ones in the bit vector `v` (1-indexed).
186188
std::vector<std::size_t> get_ones_pos(std::size_t v)
187189
{
188-
const std::size_t length = sizeof(std::size_t) * 8;
190+
const std::size_t length = sizeof(std::size_t) * CHAR_BIT;
189191
std::vector<std::size_t> result;
190192

191193
// Start from the lowest bit at position `length`
@@ -236,7 +238,7 @@ std::list<partitiont> non_leaf_enumeratort::get_partitions(
236238
return {};
237239

238240
// Number of bits at all.
239-
const std::size_t length = sizeof(std::size_t) * 8;
241+
const std::size_t length = sizeof(std::size_t) * CHAR_BIT;
240242

241243
// This bithack-based implementation works only for `n` no larger than
242244
// `length`. Use the vector-based implementation `n` is too large.

src/goto-programs/goto_trace.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ Author: Daniel Kroening
1313

1414
#include "goto_trace.h"
1515

16-
#include <ostream>
17-
1816
#include <util/arith_tools.h>
1917
#include <util/byte_operators.h>
2018
#include <util/c_types.h>
19+
#include <util/config.h>
2120
#include <util/format_expr.h>
2221
#include <util/merge_irep.h>
2322
#include <util/range.h>
@@ -28,6 +27,8 @@ Author: Daniel Kroening
2827

2928
#include "printf_formatter.h"
3029

30+
#include <ostream>
31+
3132
static optionalt<symbol_exprt> get_object_rec(const exprt &src)
3233
{
3334
if(src.id()==ID_symbol)
@@ -195,7 +196,7 @@ static std::string numeric_representation(
195196
for(const auto c : result)
196197
{
197198
oss << c;
198-
if(++i % 8 == 0 && result.size() != i)
199+
if(++i % config.ansi_c.char_width == 0 && result.size() != i)
199200
oss << ' ';
200201
}
201202
if(options.base_prefix)

src/util/pointer_offset_size.cpp

+46-35
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Author: Daniel Kroening, [email protected]
1414
#include "arith_tools.h"
1515
#include "byte_operators.h"
1616
#include "c_types.h"
17+
#include "config.h"
1718
#include "invariant.h"
1819
#include "namespace.h"
1920
#include "pointer_expr.h"
@@ -38,14 +39,14 @@ optionalt<mp_integer> member_offset(
3839
{
3940
const std::size_t w = to_c_bit_field_type(comp.type()).get_width();
4041
bit_field_bits += w;
41-
result += bit_field_bits / 8;
42-
bit_field_bits %= 8;
42+
result += bit_field_bits / config.ansi_c.char_width;
43+
bit_field_bits %= config.ansi_c.char_width;
4344
}
4445
else if(comp.type().id() == ID_bool)
4546
{
4647
++bit_field_bits;
47-
result += bit_field_bits / 8;
48-
bit_field_bits %= 8;
48+
result += bit_field_bits / config.ansi_c.char_width;
49+
bit_field_bits %= config.ansi_c.char_width;
4950
}
5051
else
5152
{
@@ -92,7 +93,7 @@ pointer_offset_size(const typet &type, const namespacet &ns)
9293
auto bits = pointer_offset_bits(type, ns);
9394

9495
if(bits.has_value())
95-
return (*bits + 7) / 8;
96+
return (*bits + config.ansi_c.char_width - 1) / config.ansi_c.char_width;
9697
else
9798
return {};
9899
}
@@ -249,16 +250,16 @@ optionalt<exprt> member_offset_expr(
249250
{
250251
std::size_t w = to_c_bit_field_type(c.type()).get_width();
251252
bit_field_bits += w;
252-
const std::size_t bytes = bit_field_bits / 8;
253-
bit_field_bits %= 8;
253+
const std::size_t bytes = bit_field_bits / config.ansi_c.char_width;
254+
bit_field_bits %= config.ansi_c.char_width;
254255
if(bytes > 0)
255256
result = plus_exprt(result, from_integer(bytes, result.type()));
256257
}
257258
else if(c.type().id() == ID_bool)
258259
{
259260
++bit_field_bits;
260-
const std::size_t bytes = bit_field_bits / 8;
261-
bit_field_bits %= 8;
261+
const std::size_t bytes = bit_field_bits / config.ansi_c.char_width;
262+
bit_field_bits %= config.ansi_c.char_width;
262263
if(bytes > 0)
263264
result = plus_exprt(result, from_integer(bytes, result.type()));
264265
}
@@ -289,7 +290,9 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
289290
auto bits = pointer_offset_bits(array_type, ns);
290291

291292
if(bits.has_value())
292-
return from_integer((*bits + 7) / 8, size_type());
293+
return from_integer(
294+
(*bits + config.ansi_c.char_width - 1) / config.ansi_c.char_width,
295+
size_type());
293296
}
294297

295298
auto sub = size_of_expr(array_type.element_type(), ns);
@@ -316,7 +319,9 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
316319
auto bits = pointer_offset_bits(vector_type, ns);
317320

318321
if(bits.has_value())
319-
return from_integer((*bits + 7) / 8, size_type());
322+
return from_integer(
323+
(*bits + config.ansi_c.char_width - 1) / config.ansi_c.char_width,
324+
size_type());
320325
}
321326

322327
auto sub = size_of_expr(vector_type.element_type(), ns);
@@ -355,16 +360,16 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
355360
{
356361
std::size_t w = to_c_bit_field_type(c.type()).get_width();
357362
bit_field_bits += w;
358-
const std::size_t bytes = bit_field_bits / 8;
359-
bit_field_bits %= 8;
363+
const std::size_t bytes = bit_field_bits / config.ansi_c.char_width;
364+
bit_field_bits %= config.ansi_c.char_width;
360365
if(bytes > 0)
361366
result = plus_exprt(result, from_integer(bytes, result.type()));
362367
}
363368
else if(c.type().id() == ID_bool)
364369
{
365370
++bit_field_bits;
366-
const std::size_t bytes = bit_field_bits / 8;
367-
bit_field_bits %= 8;
371+
const std::size_t bytes = bit_field_bits / config.ansi_c.char_width;
372+
bit_field_bits %= config.ansi_c.char_width;
368373
if(bytes > 0)
369374
result = plus_exprt(result, from_integer(bytes, result.type()));
370375
}
@@ -415,7 +420,8 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
415420
}
416421
else
417422
{
418-
mp_integer sub_bytes = (*sub_bits + 7) / 8;
423+
mp_integer sub_bytes =
424+
(*sub_bits + config.ansi_c.char_width - 1) / config.ansi_c.char_width;
419425

420426
if(max_bytes>=0)
421427
{
@@ -449,19 +455,14 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
449455
type.id()==ID_c_bit_field)
450456
{
451457
std::size_t width=to_bitvector_type(type).get_width();
452-
std::size_t bytes=width/8;
453-
if(bytes*8!=width)
458+
std::size_t bytes = width / config.ansi_c.char_width;
459+
if(bytes * config.ansi_c.char_width != width)
454460
bytes++;
455461
return from_integer(bytes, size_type());
456462
}
457463
else if(type.id()==ID_c_enum)
458464
{
459-
std::size_t width =
460-
to_bitvector_type(to_c_enum_type(type).underlying_type()).get_width();
461-
std::size_t bytes=width/8;
462-
if(bytes*8!=width)
463-
bytes++;
464-
return from_integer(bytes, size_type());
465+
return size_of_expr(to_c_enum_type(type).underlying_type(), ns);
465466
}
466467
else if(type.id()==ID_c_enum_tag)
467468
{
@@ -475,11 +476,11 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
475476
{
476477
// the following is an MS extension
477478
if(type.get_bool(ID_C_ptr32))
478-
return from_integer(4, size_type());
479+
return from_integer(32 / config.ansi_c.char_width, size_type());
479480

480481
std::size_t width=to_bitvector_type(type).get_width();
481-
std::size_t bytes=width/8;
482-
if(bytes*8!=width)
482+
std::size_t bytes = width / config.ansi_c.char_width;
483+
if(bytes * config.ansi_c.char_width != width)
483484
bytes++;
484485
return from_integer(bytes, size_type());
485486
}
@@ -497,7 +498,7 @@ optionalt<exprt> size_of_expr(const typet &type, const namespacet &ns)
497498
}
498499
else if(type.id()==ID_string)
499500
{
500-
return from_integer(32/8, size_type());
501+
return from_integer(32 / config.ansi_c.char_width, size_type());
501502
}
502503
else
503504
return {};
@@ -607,12 +608,17 @@ optionalt<exprt> get_subexpression_at_offset(
607608
// if this member completely contains the target, and this member is
608609
// byte-aligned, recurse into it
609610
if(
610-
offset_bytes * 8 >= m_offset_bits && m_offset_bits % 8 == 0 &&
611-
offset_bytes * 8 + *target_size_bits <= m_offset_bits + *m_size_bits)
611+
offset_bytes * config.ansi_c.char_width >= m_offset_bits &&
612+
m_offset_bits % config.ansi_c.char_width == 0 &&
613+
offset_bytes * config.ansi_c.char_width + *target_size_bits <=
614+
m_offset_bits + *m_size_bits)
612615
{
613616
const member_exprt member(expr, component.get_name(), component.type());
614617
return get_subexpression_at_offset(
615-
member, offset_bytes - m_offset_bits / 8, target_type_raw, ns);
618+
member,
619+
offset_bytes - m_offset_bits / config.ansi_c.char_width,
620+
target_type_raw,
621+
ns);
616622
}
617623

618624
m_offset_bits += *m_size_bits;
@@ -628,11 +634,14 @@ optionalt<exprt> get_subexpression_at_offset(
628634
// no arrays of non-byte-aligned, zero-, or unknown-sized objects
629635
if(
630636
elem_size_bits.has_value() && *elem_size_bits > 0 &&
631-
*elem_size_bits % 8 == 0 && *target_size_bits <= *elem_size_bits)
637+
*elem_size_bits % config.ansi_c.char_width == 0 &&
638+
*target_size_bits <= *elem_size_bits)
632639
{
633-
const mp_integer elem_size_bytes = *elem_size_bits / 8;
640+
const mp_integer elem_size_bytes =
641+
*elem_size_bits / config.ansi_c.char_width;
634642
const auto offset_inside_elem = offset_bytes % elem_size_bytes;
635-
const auto target_size_bytes = *target_size_bits / 8;
643+
const auto target_size_bytes =
644+
*target_size_bits / config.ansi_c.char_width;
636645
// only recurse if the cell completely contains the target
637646
if(offset_inside_elem + target_size_bytes <= elem_size_bytes)
638647
{
@@ -660,7 +669,9 @@ optionalt<exprt> get_subexpression_at_offset(
660669
continue;
661670

662671
// if this member completely contains the target, recurse into it
663-
if(offset_bytes * 8 + *target_size_bits <= *m_size_bits)
672+
if(
673+
offset_bytes * config.ansi_c.char_width + *target_size_bits <=
674+
*m_size_bits)
664675
{
665676
const member_exprt member(expr, component.get_name(), component.type());
666677
return get_subexpression_at_offset(

src/util/simplify_expr.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,8 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
821821
}
822822

823823
// circular casts through types shorter than `int`
824+
// we use fixed bit widths as this is specifically for the Java bytecode
825+
// front-end
824826
if(op_type == signedbv_typet(32) && expr.op().id() == ID_typecast)
825827
{
826828
if(expr_type==c_bool_typet(8) ||
@@ -1817,7 +1819,7 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
18171819
// the next member would be misaligned, abort
18181820
if(
18191821
!component_bits.has_value() || *component_bits == 0 ||
1820-
*component_bits % 8 != 0)
1822+
*component_bits % expr.get_bits_per_byte() != 0)
18211823
{
18221824
failed = true;
18231825
break;
@@ -1868,10 +1870,12 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
18681870
pointer_offset_bits(array_type.element_type(), ns);
18691871
if(element_bit_width.has_value() && *element_bit_width > 0)
18701872
{
1871-
if(*offset > 0 && *offset * 8 % *element_bit_width == 0)
1873+
if(
1874+
*offset > 0 &&
1875+
*offset * expr.get_bits_per_byte() % *element_bit_width == 0)
18721876
{
1873-
const auto elements_to_erase =
1874-
numeric_cast_v<std::size_t>((*offset * 8) / *element_bit_width);
1877+
const auto elements_to_erase = numeric_cast_v<std::size_t>(
1878+
(*offset * expr.get_bits_per_byte()) / *element_bit_width);
18751879
array_exprt slice = to_array_expr(expr.op());
18761880
slice.operands().erase(
18771881
slice.operands().begin(),
@@ -1953,7 +1957,7 @@ simplify_exprt::simplify_byte_update(const byte_update_exprt &expr)
19531957
if(
19541958
root_size.has_value() && *root_size >= 0 && val_size.has_value() &&
19551959
*val_size >= 0 && offset_int.has_value() && *offset_int >= 0 &&
1956-
*offset_int * 8 + *val_size <= *root_size)
1960+
*offset_int * expr.get_bits_per_byte() + *val_size <= *root_size)
19571961
{
19581962
auto root_bits =
19591963
expr2bits(root, expr.id() == ID_byte_update_little_endian, ns);

src/util/simplify_expr_struct.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#include "arith_tools.h"
1212
#include "byte_operators.h"
1313
#include "c_types.h"
14+
#include "config.h"
1415
#include "invariant.h"
1516
#include "namespace.h"
1617
#include "pointer_offset_size.h"
@@ -185,7 +186,7 @@ simplify_exprt::simplify_member(const member_exprt &expr)
185186

186187
if(target_size.has_value())
187188
{
188-
mp_integer target_bits = target_size.value() * 8;
189+
mp_integer target_bits = target_size.value() * config.ansi_c.char_width;
189190
const auto bits = expr2bits(op, true, ns);
190191

191192
if(bits.has_value() &&

0 commit comments

Comments
 (0)