Skip to content

Commit 7f6443b

Browse files
committed
The sub-size of void* is undefined; use char* as specified in the standard
This patch includes a review of all uses of functions from pointer_offset_size.h as all of those may return nil or a negative number if the size could not be determined. Calling sites need to handle those cases as appropriate in a given context.
1 parent 20de0d7 commit 7f6443b

19 files changed

+130
-15
lines changed

regression/cbmc/void_pointer1/main.c

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
char buffer[2];
2+
int length = 2;
3+
4+
void func(void* buf, int len)
5+
{
6+
while( len-- )
7+
*(char *)buf++;
8+
}
9+
10+
void main(){
11+
func(buffer,length);
12+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--pointer-check
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

regression/cbmc/void_pointer2/main.c

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
char buffer[2];
2+
int length = 2;
3+
4+
void func(void* buf, int len)
5+
{
6+
while( len-- )
7+
*(char *)buf++;
8+
}
9+
10+
void main(){
11+
func(buffer,length);
12+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--pointer-check --no-simplify --unwind 3
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/analyses/goto_rw.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ void rw_range_sett::get_objects_complex(
149149

150150
range_spect sub_size=
151151
to_range_spect(pointer_offset_bits(op.type().subtype(), ns));
152+
assert(sub_size>0);
152153
range_spect offset=
153154
(range_start==-1 || expr.id()==ID_complex_real) ? 0 : sub_size;
154155

src/ansi-c/c_typecheck_expr.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1318,8 +1318,8 @@ void c_typecheck_baset::typecheck_expr_typecast(exprt &expr)
13181318
// an integer/float of the same size
13191319
if((expr_type.id()==ID_signedbv ||
13201320
expr_type.id()==ID_unsignedbv) &&
1321-
pointer_offset_size(expr_type, *this)==
1322-
pointer_offset_size(op_vector_type, *this))
1321+
pointer_offset_bits(expr_type, *this)==
1322+
pointer_offset_bits(op_vector_type, *this))
13231323
{
13241324
}
13251325
else

src/ansi-c/padding.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ void add_padding(union_typet &type, const namespacet &ns)
339339
mp_integer max_alignment=alignment(type, ns)*8;
340340
mp_integer size_bits=pointer_offset_bits(type, ns);
341341

342+
if(size_bits<0)
343+
throw "type of unknown size:\n"+type.pretty();
344+
342345
union_typet::componentst &components=type.components();
343346

344347
// Is the union packed?

src/goto-instrument/alignment_checks.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ void print_struct_alignment_problems(
6060
const namespacet ns(symbol_table);
6161
mp_integer size=pointer_offset_size(it_type, ns);
6262

63+
if(size<0)
64+
throw "type of unknown size:\n"+it_type.pretty();
65+
6366
cumulated_length+=size;
6467
// [it_mem;it_next] cannot be covered by an instruction
6568
if(cumulated_length>config.ansi_c.memory_operand_size)
@@ -99,6 +102,9 @@ void print_struct_alignment_problems(
99102
const mp_integer size=
100103
pointer_offset_size(array.subtype(), ns);
101104

105+
if(size<0)
106+
throw "type of unknown size:\n"+it_type.pretty();
107+
102108
if(2*integer2long(size)<=config.ansi_c.memory_operand_size)
103109
{
104110
out << "\nWARNING: "

src/pointer-analysis/value_set.cpp

+24-4
Original file line numberDiff line numberDiff line change
@@ -717,10 +717,23 @@ void value_sett::get_value_set_rec(
717717

718718
if(i_is_set)
719719
{
720-
i*=pointer_offset_size(ptr_operand.type().subtype(), ns);
720+
typet pointer_sub_type=ptr_operand.type().subtype();
721+
if(pointer_sub_type.id()==ID_empty)
722+
pointer_sub_type=char_type();
721723

722-
if(expr.id()==ID_minus)
723-
i.negate();
724+
mp_integer size=pointer_offset_size(pointer_sub_type, ns);
725+
726+
if(size<=0)
727+
{
728+
i_is_set=false;
729+
}
730+
else
731+
{
732+
i*=size;
733+
734+
if(expr.id()==ID_minus)
735+
i.negate();
736+
}
724737
}
725738

726739
get_value_set_rec(
@@ -1155,7 +1168,14 @@ void value_sett::get_reference_set_rec(
11551168
}
11561169
else if(!to_integer(offset, i) &&
11571170
o.offset_is_zero())
1158-
o.offset=i*pointer_offset_size(array_type.subtype(), ns);
1171+
{
1172+
mp_integer size=pointer_offset_size(array_type.subtype(), ns);
1173+
1174+
if(size<=0)
1175+
o.offset_is_set=false;
1176+
else
1177+
o.offset=i*size;
1178+
}
11591179
else
11601180
o.offset_is_set=false;
11611181

src/pointer-analysis/value_set_dereference.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,10 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
566566
// no need to adjust offset
567567
adjusted_offset=offset;
568568
}
569+
else if(element_size<=0)
570+
{
571+
throw "unknown or invalid type size of:\n"+dereference_type.pretty();
572+
}
569573
else
570574
{
571575
exprt element_size_expr=
@@ -965,7 +969,12 @@ bool value_set_dereferencet::memory_model_bytes(
965969
// upper bound
966970
{
967971
mp_integer from_width=pointer_offset_size(from_type, ns);
972+
if(from_width<=0)
973+
throw "unknown or invalid type size:\n"+from_type.pretty();
974+
968975
mp_integer to_width=pointer_offset_size(to_type, ns);
976+
if(to_width<=0)
977+
throw "unknown or invalid type size:\n"+to_type.pretty();
969978

970979
exprt bound=from_integer(from_width-to_width, offset.type());
971980

src/solvers/cvc/cvc_conv.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,7 @@ void cvc_convt::convert_address_of_rec(const exprt &expr)
835835
to_struct_type(struct_op.type()),
836836
component_name,
837837
ns);
838+
assert(offset>=0);
838839

839840
typet index_type(ID_unsignedbv);
840841
index_type.set(ID_width, config.ansi_c.pointer_width);

src/solvers/dplib/dplib_conv.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ void dplib_convt::convert_address_of_rec(const exprt &expr)
218218

219219
mp_integer offset=member_offset(ns,
220220
to_struct_type(struct_op.type()), component_name);
221+
assert(offset>=0);
221222

222223
typet index_type(ID_unsignedbv);
223224
index_type.set(ID_width, config.ansi_c.pointer_width);

src/solvers/flattening/bv_pointers.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9+
#include <util/c_types.h>
910
#include <util/config.h>
1011
#include <util/arith_tools.h>
1112
#include <util/prefix.h>
@@ -185,6 +186,7 @@ bool bv_pointerst::convert_address_of_rec(
185186
// get size
186187
mp_integer size=
187188
pointer_offset_size(array_type.subtype(), ns);
189+
assert(size>0);
188190

189191
offset_arithmetic(bv, size, index);
190192
assert(bv.size()==bits);
@@ -205,6 +207,7 @@ bool bv_pointerst::convert_address_of_rec(
205207
mp_integer offset=member_offset(
206208
to_struct_type(struct_op_type),
207209
member_expr.get_component_name(), ns);
210+
assert(offset>=0);
208211

209212
// add offset
210213
offset_arithmetic(bv, offset);
@@ -375,7 +378,12 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
375378
count++;
376379
bv=convert_bv(*it);
377380
assert(bv.size()==bits);
378-
size=pointer_offset_size(it->type().subtype(), ns);
381+
382+
typet pointer_sub_type=it->type().subtype();
383+
if(pointer_sub_type.id()==ID_empty)
384+
pointer_sub_type=char_type();
385+
size=pointer_offset_size(pointer_sub_type, ns);
386+
assert(size>0);
379387
}
380388
}
381389

@@ -449,6 +457,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
449457

450458
mp_integer element_size=
451459
pointer_offset_size(expr.op0().type().subtype(), ns);
460+
assert(element_size>0);
452461

453462
offset_arithmetic(bv, element_size, neg_op1);
454463

@@ -517,6 +526,7 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
517526

518527
mp_integer element_size=
519528
pointer_offset_size(expr.op0().type().subtype(), ns);
529+
assert(element_size>0);
520530

521531
if(element_size!=1)
522532
{

src/solvers/flattening/flatten_byte_operators.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ exprt flatten_byte_update(
197197

198198
mp_integer element_size=
199199
pointer_offset_size(src.op2().type(), ns);
200+
if(element_size<0)
201+
throw "byte_update of unknown width:\n"+src.pretty();
200202

201203
const typet &t=ns.follow(src.op0().type());
202204

@@ -378,9 +380,9 @@ exprt flatten_byte_update(
378380
t.id()==ID_pointer)
379381
{
380382
// do a shift, mask and OR
381-
std::size_t width=integer2size_t(pointer_offset_size(t, ns)*8);
382-
383-
assert(width!=0);
383+
mp_integer type_width=pointer_offset_bits(t, ns);
384+
assert(type_width>0);
385+
std::size_t width=integer2size_t(type_width);
384386

385387
if(element_size*8>width)
386388
throw "flatten_byte_update to update element that is too large";

src/solvers/flattening/pointer_logic.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ exprt pointer_logict::object_rec(
200200
mp_integer size=
201201
pointer_offset_size(src.type().subtype(), ns);
202202

203-
if(size==0)
203+
if(size<=0)
204204
return src;
205205

206206
mp_integer index=offset/size;
@@ -234,6 +234,7 @@ exprt pointer_logict::object_rec(
234234
const typet &subtype=it->type();
235235

236236
mp_integer sub_size=pointer_offset_size(subtype, ns);
237+
assert(sub_size>0);
237238
mp_integer new_offset=current_offset+sub_size;
238239

239240
if(new_offset>offset)

src/solvers/smt1/smt1_conv.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ void smt1_convt::convert_address_of_rec(
432432
member_expr.get_component_name();
433433

434434
mp_integer offset=member_offset(struct_type, component_name, ns);
435+
assert(offset>=0);
435436

436437
typet index_type(ID_unsignedbv);
437438
index_type.set(ID_width, boolbv_width(result_type));
@@ -2333,6 +2334,7 @@ void smt1_convt::convert_plus(const plus_exprt &expr)
23332334

23342335
mp_integer element_size=
23352336
pointer_offset_size(expr.type().subtype(), ns);
2337+
assert(element_size>0);
23362338

23372339
// adjust width if needed
23382340
if(boolbv_width(i.type())!=boolbv_width(expr.type()))

src/solvers/smt2/smt2_conv.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ void smt2_convt::convert_address_of_rec(
694694
member_expr.get_component_name();
695695

696696
mp_integer offset=member_offset(struct_type, component_name, ns);
697+
assert(offset>=0);
697698

698699
unsignedbv_typet index_type;
699700
index_type.set_width(boolbv_width(result_type));
@@ -3253,6 +3254,7 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
32533254

32543255
mp_integer element_size=
32553256
pointer_offset_size(expr.type().subtype(), ns);
3257+
assert(element_size>0);
32563258

32573259
out << "(bvadd ";
32583260
convert_expr(p);
@@ -3469,6 +3471,7 @@ void smt2_convt::convert_minus(const minus_exprt &expr)
34693471
// Pointer difference.
34703472
mp_integer element_size=
34713473
pointer_offset_size(expr.op0().type().subtype(), ns);
3474+
assert(element_size>0);
34723475

34733476
if(element_size>=2)
34743477
out << "(bvsdiv ";

src/util/pointer_offset_size.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ mp_integer pointer_offset_bits(
130130
if(type.id()==ID_array)
131131
{
132132
mp_integer sub=pointer_offset_bits(type.subtype(), ns);
133+
if(sub<0)
134+
return -1;
133135

134136
// get size
135137
const exprt &size=to_array_type(type).size();
@@ -145,6 +147,8 @@ mp_integer pointer_offset_bits(
145147
else if(type.id()==ID_vector)
146148
{
147149
mp_integer sub=pointer_offset_bits(type.subtype(), ns);
150+
if(sub<0)
151+
return -1;
148152

149153
// get size
150154
const exprt &size=to_vector_type(type).size();
@@ -160,6 +164,9 @@ mp_integer pointer_offset_bits(
160164
else if(type.id()==ID_complex)
161165
{
162166
mp_integer sub=pointer_offset_bits(type.subtype(), ns);
167+
if(sub<0)
168+
return -1;
169+
163170
return sub*2;
164171
}
165172
else if(type.id()==ID_struct)
@@ -201,6 +208,8 @@ mp_integer pointer_offset_bits(
201208
{
202209
const typet &subtype=it->type();
203210
mp_integer sub_size=pointer_offset_bits(subtype, ns);
211+
if(sub_size==-1)
212+
return -1;
204213
if(sub_size>result)
205214
result=sub_size;
206215
}
@@ -467,6 +476,11 @@ exprt size_of_expr(
467476
else
468477
sub_size=pointer_offset_size(subtype, ns);
469478

479+
if(sub_size==-1)
480+
{
481+
result=-1;
482+
break;
483+
}
470484
if(sub_size>result)
471485
result=sub_size;
472486
}
@@ -566,7 +580,7 @@ mp_integer compute_pointer_offset(
566580

567581
mp_integer i;
568582

569-
if(sub_size!=0 && !to_integer(expr.op1(), i))
583+
if(sub_size>0 && !to_integer(expr.op1(), i))
570584
return o+i*sub_size;
571585
}
572586

src/util/simplify_expr_pointer.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -383,12 +383,14 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr)
383383
if(ptr_expr.size()!=1 || int_expr.empty())
384384
return true;
385385

386-
typet pointer_type=ptr_expr.front().type();
386+
typet pointer_sub_type=ptr_expr.front().type().subtype();
387+
if(pointer_sub_type.id()==ID_empty)
388+
pointer_sub_type=char_type();
387389

388390
mp_integer element_size=
389-
pointer_offset_size(pointer_type.subtype(), ns);
391+
pointer_offset_size(pointer_sub_type, ns);
390392

391-
if(element_size==0)
393+
if(element_size<0)
392394
return true;
393395

394396
// this might change the type of the pointer!

0 commit comments

Comments
 (0)