Skip to content

Commit b26ad8b

Browse files
tautschnigRemi Delmas
and
Remi Delmas
committed
String abstraction: gracefully handle type casts from non-char types
The previous implementation would only work when type casts were limited to casts to and from char-sized bitvector types. We lose precision when casting from non-char types, but shouldn't end up hitting "UNREACHABLE." Co-authored-by: Remi Delmas <[email protected]>
1 parent 1fd7a56 commit b26ad8b

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
int main()
6+
{
7+
size_t len;
8+
__CPROVER_assume(0 < len);
9+
uint16_t *data = malloc(len * sizeof(uint16_t));
10+
if(data)
11+
{
12+
len = (len + 1) * sizeof(uint16_t);
13+
uint16_t *ptr = malloc(len);
14+
if(ptr)
15+
{
16+
memcpy(ptr, data, len);
17+
ptr[len] = 0;
18+
}
19+
}
20+
return 0;
21+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
--string-abstraction
4+
^VERIFICATION FAILED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring
9+
^Invariant check failed
10+
--
11+
String abstraction is not necessarily precise enough to reason across type casts
12+
from non-char pointer types, but must not fail to process such examples.

src/goto-programs/string_abstraction.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,12 +651,18 @@ exprt string_abstractiont::build(
651651
// take care of pointer typecasts now
652652
if(pointer.id()==ID_typecast)
653653
{
654+
const exprt &op = to_typecast_expr(pointer).op();
655+
654656
// cast from another pointer type?
655-
if(to_typecast_expr(pointer).op().type().id() != ID_pointer)
657+
if(
658+
op.type().id() != ID_pointer ||
659+
!is_char_type(to_pointer_type(op.type()).base_type()))
660+
{
656661
return build_unknown(what, write);
662+
}
657663

658664
// recursive call
659-
return build(to_typecast_expr(pointer).op(), what, write, source_location);
665+
return build(op, what, write, source_location);
660666
}
661667

662668
exprt str_struct;

0 commit comments

Comments
 (0)