Skip to content

Commit 6b5d608

Browse files
committed
The size of arrays is unsigned
Arrays have an unsigned size, and this must also be true when converting string constants to arrays. Using signed size types resulted in invariant failures in the simplifier, which were triggered by passing in arrays with a negative size. Observed on several SV-COMP benchmarks in the device drivers category, for example (with --unwind 2): ldv-linux-3.16-rc1/43_2a_bitvector_linux-3.16-rc1.tar.xz-43_2a-drivers--net--wireless--iwlwifi--iwlwifi.ko-entry_point.cil.out.i
1 parent f250e8b commit 6b5d608

File tree

11 files changed

+15
-12
lines changed

11 files changed

+15
-12
lines changed
419 Bytes
Binary file not shown.
420 Bytes
Binary file not shown.
419 Bytes
Binary file not shown.
418 Bytes
Binary file not shown.

regression/goto-harness/havoc-global-int-02/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-y-snapshot.json --initial-goto-location main:7 --havoc-variables y
3+
--harness-type initialise-with-memory-snapshot --memory-snapshot ../load-snapshot-json-snapshots/global-int-x-y-snapshot.json --initial-goto-location main:5 --havoc-variables y
44
^\[main.assertion.1\] line \d+ assertion y \+ 2 > y: FAILURE$
55
^\[main.assertion.2\] line \d+ assertion 0: FAILURE$
66
^EXIT=10$

src/ansi-c/c_typecheck_initializer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ exprt c_typecheck_baset::do_initializer_list(
951951
// make complete by setting array size
952952
size_t size=result.operands().size();
953953
result.type().id(ID_array);
954-
result.type().set(ID_size, from_integer(size, index_type()));
954+
result.type().set(ID_size, from_integer(size, size_type()));
955955
}
956956

957957
return result;

src/ansi-c/c_typecheck_type.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,6 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
559559
if(size.is_not_nil())
560560
{
561561
typecheck_expr(size);
562-
make_index_type(size);
563562

564563
// The size need not be a constant!
565564
// We simplify it, for the benefit of array initialisation.
@@ -587,10 +586,13 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
587586
throw 0;
588587
}
589588

589+
implicit_typecast(tmp_size, size_type());
590+
simplify(tmp_size, *this);
590591
size=tmp_size;
591592
}
592593
else if(tmp_size.id()==ID_infinity)
593594
{
595+
tmp_size.type() = size_type();
594596
size=tmp_size;
595597
}
596598
else if(tmp_size.id()==ID_symbol &&
@@ -602,6 +604,7 @@ void c_typecheck_baset::typecheck_array_type(array_typet &type)
602604
// Of course we can modify a 'const' symbol, e.g.,
603605
// using a pointer type cast. Interestingly,
604606
// at least gcc 4.2.1 makes the very same mistake!
607+
implicit_typecast(tmp_size, size_type());
605608
size=tmp_size;
606609
}
607610
else
@@ -985,7 +988,7 @@ void c_typecheck_baset::typecheck_compound_body(
985988

986989
// make it zero-length
987990
c_type.id(ID_array);
988-
c_type.set(ID_size, from_integer(0, index_type()));
991+
c_type.set(ID_size, from_integer(0, size_type()));
989992
}
990993
}
991994
}

src/ansi-c/literals/convert_string_literal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ exprt convert_string_literal(const std::string &src)
132132
result.set(ID_C_string_constant, true);
133133
result.type()=typet(ID_array);
134134
result.type().subtype()=subtype;
135-
result.type().set(ID_size, from_integer(value.size(), index_type()));
135+
result.type().set(ID_size, from_integer(value.size(), size_type()));
136136

137137
result.operands().resize(value.size());
138138
for(std::size_t i=0; i<value.size(); i++)

src/cpp/cpp_typecheck_compound_type.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,8 @@ void cpp_typecheckt::check_fixed_size_array(typet &type)
774774
array_type.size() = symbol.value;
775775
}
776776

777-
make_constant_index(array_type.size());
777+
implicit_typecast(array_type.size(), size_type());
778+
make_constant(array_type.size());
778779
}
779780

780781
// recursive call for multi-dimensional arrays

src/cpp/cpp_typecheck_expr.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Author: Daniel Kroening, [email protected]
2121
#include <util/expr_initializer.h>
2222
#include <util/mathematical_types.h>
2323
#include <util/pointer_offset_size.h>
24+
#include <util/simplify_expr.h>
2425

2526
#include <ansi-c/c_qualifiers.h>
2627

@@ -758,10 +759,8 @@ void cpp_typecheckt::typecheck_expr_new(exprt &expr)
758759
exprt &size=to_array_type(expr.type()).size();
759760
typecheck_expr(size);
760761

761-
bool size_is_unsigned=(size.type().id()==ID_unsignedbv);
762-
bitvector_typet integer_type(
763-
size_is_unsigned ? ID_unsignedbv : ID_signedbv, config.ansi_c.int_width);
764-
implicit_typecast(size, integer_type);
762+
implicit_typecast(size, size_type());
763+
simplify(size, *this);
765764

766765
expr.set(ID_statement, ID_cpp_new_array);
767766

0 commit comments

Comments
 (0)