Skip to content

Commit 05d547a

Browse files
Fix SM access involving floats
1 parent b3896e5 commit 05d547a

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"
@@ -357,8 +358,12 @@ exprt duplicate_per_byte(
357358
const typet &output_type,
358359
const namespacet &ns)
359360
{
360-
if(output_type.id() == ID_unsignedbv || output_type.id() == ID_signedbv)
361+
if(
362+
output_type.id() == ID_unsignedbv || output_type.id() == ID_signedbv ||
363+
output_type.id() == ID_floatbv)
361364
{
365+
const typet unsigned_output_type =
366+
unsignedbv_typet(to_bitvector_type(output_type).get_width());
362367
const size_t size = to_bitvector_type(output_type).get_width() / 8;
363368
if(init_byte_expr.is_constant())
364369
{
@@ -367,17 +372,23 @@ exprt duplicate_per_byte(
367372
for(size_t i = 1; i < size; ++i) {
368373
duplicated_value = bitwise_or(duplicated_value << 8, value);
369374
}
370-
return from_integer(duplicated_value, output_type);
375+
exprt constant_expr =
376+
from_integer(duplicated_value, unsigned_output_type);
377+
return make_byte_extract(
378+
constant_expr, from_integer(0, size_type()), output_type);
371379
}
372380
exprt::operandst values;
373381
values.push_back(
374-
typecast_exprt::conditional_cast(init_byte_expr, output_type));
382+
typecast_exprt::conditional_cast(init_byte_expr, unsigned_output_type));
375383
for(size_t i = 1; i < size; ++i) {
376384
values.push_back(shl_exprt(
377-
typecast_exprt::conditional_cast(init_byte_expr, output_type),
385+
typecast_exprt::conditional_cast(init_byte_expr, unsigned_output_type),
378386
from_integer(8 * i, size_type())));
379387
}
380-
return or_values(values, output_type);
388+
return make_byte_extract(
389+
or_values(values, unsigned_output_type),
390+
from_integer(0, size_type()),
391+
output_type);
381392
}
382393
return typecast_exprt::conditional_cast(init_byte_expr, output_type);
383394
}

0 commit comments

Comments
 (0)