Skip to content

Commit 302bfde

Browse files
Fix SM access involving floats
1 parent 56f6925 commit 302bfde

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

src/goto-symex/symex_shadow_memory_util.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#include "symex_shadow_memory_util.h"
22

3-
#include <langapi/language_util.h>
4-
53
#include <util/arith_tools.h>
64
#include <util/bitvector_expr.h>
5+
#include <util/byte_operators.h>
76
#include <util/c_types.h>
7+
#include <util/config.h>
8+
#include <util/expr_initializer.h>
89
#include <util/format_expr.h>
910
#include <util/pointer_expr.h>
10-
#include <util/expr_initializer.h>
11+
12+
#include <langapi/language_util.h>
1113

1214
void log_exact_match(
1315
const namespacet &ns,
@@ -315,6 +317,18 @@ const exprt &get_field_init_expr(
315317
return field_type_it->second;
316318
}
317319

320+
static exprt conditional_cast_floatbv_to_unsignedbv(const exprt &value)
321+
{
322+
if(value.type().id() != ID_floatbv)
323+
{
324+
return value;
325+
}
326+
return make_byte_extract(
327+
value,
328+
from_integer(0, unsigned_int_type()),
329+
unsignedbv_typet(to_bitvector_type(value.type()).get_width()));
330+
}
331+
318332
static void max_element(
319333
const exprt &element,
320334
const typet &field_type,
@@ -348,13 +362,14 @@ static void max_over_bytes(
348362
}
349363

350364
static void max_elements(
351-
const exprt &element,
365+
exprt element,
352366
const typet &field_type,
353367
const namespacet &ns,
354368
const messaget &log,
355369
const bool is_union,
356370
exprt &max)
357371
{
372+
element = conditional_cast_floatbv_to_unsignedbv(element);
358373
if(element.type().id() == ID_unsignedbv || element.type().id() == ID_signedbv)
359374
{
360375
if(is_union)
@@ -432,7 +447,9 @@ exprt compute_max_over_cells(
432447
<< messaget::eom;
433448
}
434449
}
435-
return typecast_exprt::conditional_cast(expr, field_type);
450+
// TODO: This is incorrect when accessing non-0 offsets of scalars.
451+
return typecast_exprt::conditional_cast(
452+
conditional_cast_floatbv_to_unsignedbv(expr), field_type);
436453
}
437454

438455
static void or_over_bytes(
@@ -462,13 +479,14 @@ static exprt or_values(const exprt::operandst &values, const typet &field_type)
462479
}
463480

464481
static void or_elements(
465-
const exprt &element,
482+
exprt element,
466483
const typet &field_type,
467484
const namespacet &ns,
468485
const messaget &log,
469486
const bool is_union,
470487
exprt::operandst &values)
471488
{
489+
element = conditional_cast_floatbv_to_unsignedbv(element);
472490
if(element.type().id() == ID_unsignedbv || element.type().id() == ID_signedbv)
473491
{
474492
exprt value = element;
@@ -511,7 +529,7 @@ exprt compute_or_over_cells(
511529
continue;
512530
}
513531
or_elements(
514-
member_exprt(expr, component),
532+
member_exprt(expr, component),
515533
field_type,
516534
ns,
517535
log,
@@ -550,11 +568,13 @@ exprt compute_or_over_cells(
550568
exprt::operandst values;
551569
if(is_union)
552570
{
553-
or_over_bytes(expr, type, field_type, values);
571+
or_over_bytes(
572+
conditional_cast_floatbv_to_unsignedbv(expr), type, field_type, values);
554573
}
555574
else
556575
{
557-
values.push_back(typecast_exprt::conditional_cast(expr, field_type));
576+
values.push_back(typecast_exprt::conditional_cast(
577+
conditional_cast_floatbv_to_unsignedbv(expr), field_type));
558578
}
559579
return or_values(values, field_type);
560580
}

src/util/expr_initializer.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Author: Daniel Kroening, [email protected]
1313

1414
#include "arith_tools.h"
1515
#include "bitvector_expr.h"
16+
#include "byte_operators.h"
1617
#include "c_types.h"
1718
#include "magic.h"
1819
#include "namespace.h" // IWYU pragma: keep
@@ -350,8 +351,12 @@ exprt duplicate_per_byte(
350351
const typet &output_type,
351352
const namespacet &ns)
352353
{
353-
if(output_type.id() == ID_unsignedbv || output_type.id() == ID_signedbv)
354+
if(
355+
output_type.id() == ID_unsignedbv || output_type.id() == ID_signedbv ||
356+
output_type.id() == ID_floatbv)
354357
{
358+
const typet unsigned_output_type =
359+
unsignedbv_typet(to_bitvector_type(output_type).get_width());
355360
const size_t size = to_bitvector_type(output_type).get_width() / 8;
356361
if(init_byte_expr.is_constant())
357362
{
@@ -360,17 +365,23 @@ exprt duplicate_per_byte(
360365
for(size_t i = 1; i < size; ++i) {
361366
duplicated_value = bitwise_or(duplicated_value << 8, value);
362367
}
363-
return from_integer(duplicated_value, output_type);
368+
exprt constant_expr =
369+
from_integer(duplicated_value, unsigned_output_type);
370+
return make_byte_extract(
371+
constant_expr, from_integer(0, size_type()), output_type);
364372
}
365373
exprt::operandst values;
366374
values.push_back(
367-
typecast_exprt::conditional_cast(init_byte_expr, output_type));
375+
typecast_exprt::conditional_cast(init_byte_expr, unsigned_output_type));
368376
for(size_t i = 1; i < size; ++i) {
369377
values.push_back(shl_exprt(
370-
typecast_exprt::conditional_cast(init_byte_expr, output_type),
378+
typecast_exprt::conditional_cast(init_byte_expr, unsigned_output_type),
371379
from_integer(8 * i, size_type())));
372380
}
373-
return or_values(values, output_type);
381+
return make_byte_extract(
382+
or_values(values, unsigned_output_type),
383+
from_integer(0, size_type()),
384+
output_type);
374385
}
375386
return typecast_exprt::conditional_cast(init_byte_expr, output_type);
376387
}

0 commit comments

Comments
 (0)