Skip to content

Commit d285eb8

Browse files
author
Daniel Kroening
committed
pointer_offset_size functions now use optional
This reminds the user of these functionst that they might return an error.
1 parent 67506ee commit d285eb8

24 files changed

+276
-232
lines changed

jbmc/src/java_bytecode/remove_java_new.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,12 @@ goto_programt::targett remove_java_newt::lower_java_new(
8686
typet object_type = rhs.type().subtype();
8787

8888
// build size expression
89-
exprt object_size = size_of_expr(object_type, ns);
90-
CHECK_RETURN(object_size.is_not_nil());
89+
const auto object_size = size_of_expr(object_type, ns);
90+
CHECK_RETURN(object_size.has_value());
9191

9292
// we produce a malloc side-effect, which stays
9393
side_effect_exprt malloc_expr(ID_allocate, rhs.type(), location);
94-
malloc_expr.copy_to_operands(object_size);
94+
malloc_expr.copy_to_operands(*object_size);
9595
// could use true and get rid of the code below
9696
malloc_expr.copy_to_operands(false_exprt());
9797
*target =
@@ -138,12 +138,12 @@ goto_programt::targett remove_java_newt::lower_java_new_array(
138138
PRECONDITION(ns.follow(object_type).id() == ID_struct);
139139

140140
// build size expression
141-
exprt object_size = size_of_expr(object_type, ns);
142-
CHECK_RETURN(!object_size.is_nil());
141+
const auto object_size = size_of_expr(object_type, ns);
142+
CHECK_RETURN(object_size.has_value());
143143

144144
// we produce a malloc side-effect, which stays
145145
side_effect_exprt malloc_expr(ID_allocate, rhs.type(), location);
146-
malloc_expr.copy_to_operands(object_size);
146+
malloc_expr.copy_to_operands(*object_size);
147147
// code use true and get rid of the code below
148148
malloc_expr.copy_to_operands(false_exprt());
149149

src/analyses/goto_check.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,8 +1056,10 @@ void goto_checkt::pointer_validity_check(
10561056

10571057
const exprt &pointer=expr.pointer();
10581058

1059-
auto conditions =
1060-
address_check(pointer, size_of_expr(expr.type(), ns));
1059+
auto size_of_expr_opt = size_of_expr(expr.type(), ns);
1060+
CHECK_RETURN(size_of_expr_opt.has_value());
1061+
1062+
auto conditions = address_check(pointer, size_of_expr_opt.value());
10611063

10621064
for(const auto &c : conditions)
10631065
{
@@ -1329,12 +1331,11 @@ void goto_checkt::bounds_check(
13291331
expr,
13301332
guard);
13311333

1332-
exprt type_size=size_of_expr(ode.root_object().type(), ns);
1333-
if(type_size.is_not_nil())
1334-
type_matches_size=
1335-
equal_exprt(
1336-
size,
1337-
typecast_exprt(type_size, size.type()));
1334+
auto type_size_opt = size_of_expr(ode.root_object().type(), ns);
1335+
1336+
if(type_size_opt.has_value())
1337+
type_matches_size =
1338+
equal_exprt(size, typecast_exprt(type_size_opt.value(), size.type()));
13381339
}
13391340

13401341
const exprt &size=array_type.id()==ID_array ?
@@ -1360,12 +1361,14 @@ void goto_checkt::bounds_check(
13601361
// that member, it behaves as if that member were replaced with the longest
13611362
// array (with the same element type) that would not make the structure
13621363
// larger than the object being accessed; [...]
1363-
const exprt type_size = size_of_expr(ode.root_object().type(), ns);
1364+
const auto type_size_opt = size_of_expr(ode.root_object().type(), ns);
1365+
CHECK_RETURN(type_size_opt.has_value());
13641366

13651367
binary_relation_exprt inequality(
1366-
typecast_exprt::conditional_cast(ode.offset(), type_size.type()),
1368+
typecast_exprt::conditional_cast(
1369+
ode.offset(), type_size_opt.value().type()),
13671370
ID_lt,
1368-
type_size);
1371+
type_size_opt.value());
13691372

13701373
add_guarded_claim(
13711374
implies_exprt(type_matches_size, inequality),
@@ -1542,10 +1545,9 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
15421545

15431546
// we rewrite s->member into *(s+member_offset)
15441547
// to avoid requiring memory safety of the entire struct
1548+
auto member_offset_opt = member_offset_expr(member, ns);
15451549

1546-
exprt member_offset=member_offset_expr(member, ns);
1547-
1548-
if(member_offset.is_not_nil())
1550+
if(member_offset_opt.has_value())
15491551
{
15501552
pointer_typet new_pointer_type = to_pointer_type(deref.pointer().type());
15511553
new_pointer_type.subtype() = expr.type();
@@ -1557,7 +1559,8 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
15571559
const exprt new_address = typecast_exprt(
15581560
plus_exprt(
15591561
char_pointer,
1560-
typecast_exprt::conditional_cast(member_offset, pointer_diff_type())),
1562+
typecast_exprt::conditional_cast(
1563+
member_offset_opt.value(), pointer_diff_type())),
15611564
char_pointer.type());
15621565

15631566
const exprt new_address_casted =

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -609,21 +609,20 @@ void c_typecheck_baset::typecheck_expr_builtin_offsetof(exprt &expr)
609609

610610
if(type.id()==ID_struct)
611611
{
612-
exprt o=
613-
member_offset_expr(
614-
to_struct_type(type), component_name, *this);
612+
auto o_opt =
613+
member_offset_expr(to_struct_type(type), component_name, *this);
615614

616-
if(o.is_nil())
615+
if(!o_opt.has_value())
617616
{
618617
error().source_location = expr.source_location();
619618
error() << "offsetof failed to determine offset of `"
620619
<< component_name << "'" << eom;
621620
throw 0;
622621
}
623622

624-
o = typecast_exprt::conditional_cast(o, size_type());
625-
626-
result=plus_exprt(result, o);
623+
result = plus_exprt(
624+
result,
625+
typecast_exprt::conditional_cast(o_opt.value(), size_type()));
627626
}
628627

629628
type=struct_union_type.get_component(component_name).type();
@@ -643,20 +642,21 @@ void c_typecheck_baset::typecheck_expr_builtin_offsetof(exprt &expr)
643642
{
644643
if(type.id()==ID_struct)
645644
{
646-
exprt o = member_offset_expr(
645+
auto o_opt = member_offset_expr(
647646
to_struct_type(type), c.get_name(), *this);
648647

649-
if(o.is_nil())
648+
if(!o_opt.has_value())
650649
{
651650
error().source_location = expr.source_location();
652651
error() << "offsetof failed to determine offset of `"
653652
<< component_name << "'" << eom;
654653
throw 0;
655654
}
656655

657-
o = typecast_exprt::conditional_cast(o, size_type());
658-
659-
result=plus_exprt(result, o);
656+
result = plus_exprt(
657+
result,
658+
typecast_exprt::conditional_cast(
659+
o_opt.value(), size_type()));
660660
}
661661

662662
typet tmp = follow(c.type());
@@ -695,11 +695,18 @@ void c_typecheck_baset::typecheck_expr_builtin_offsetof(exprt &expr)
695695
// still need to typecheck index
696696
typecheck_expr(index);
697697

698-
exprt sub_size=size_of_expr(type.subtype(), *this);
698+
auto sub_size_opt = size_of_expr(type.subtype(), *this);
699+
700+
if(!sub_size_opt.has_value())
701+
{
702+
error().source_location = expr.source_location();
703+
error() << "offsetof failed to determine array element size" << eom;
704+
throw 0;
705+
}
699706

700707
index = typecast_exprt::conditional_cast(index, size_type());
701708

702-
result=plus_exprt(result, mult_exprt(sub_size, index));
709+
result = plus_exprt(result, mult_exprt(sub_size_opt.value(), index));
703710

704711
typet tmp=type.subtype();
705712
type=tmp;
@@ -966,18 +973,20 @@ void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr)
966973
{
967974
// This is a gcc extension.
968975
// https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
969-
new_expr = size_of_expr(char_type(), *this);
976+
new_expr = from_integer(1, size_type());
970977
}
971978
else
972979
{
973-
new_expr = size_of_expr(type, *this);
980+
auto size_of_opt = size_of_expr(type, *this);
974981

975-
if(new_expr.is_nil())
982+
if(!size_of_opt.has_value())
976983
{
977984
error().source_location = expr.source_location();
978985
error() << "type has no size: " << to_string(type) << eom;
979986
throw 0;
980987
}
988+
989+
new_expr = size_of_opt.value();
981990
}
982991

983992
new_expr.swap(expr);

src/ansi-c/c_typecheck_type.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,11 +693,19 @@ void c_typecheck_baset::typecheck_vector_type(typet &type)
693693
}
694694

695695
// the subtype must have constant size
696-
exprt sub_size_expr = size_of_expr(subtype, *this);
696+
auto sub_size_expr_opt = size_of_expr(subtype, *this);
697697

698-
simplify(sub_size_expr, *this);
698+
if(!sub_size_expr_opt.has_value())
699+
{
700+
error().source_location = source_location;
701+
error() << "failed to determine size of vector base type `"
702+
<< to_string(subtype) << "'" << eom;
703+
throw 0;
704+
}
705+
706+
simplify(sub_size_expr_opt.value(), *this);
699707

700-
const auto sub_size = numeric_cast<mp_integer>(sub_size_expr);
708+
const auto sub_size = numeric_cast<mp_integer>(sub_size_expr_opt.value());
701709

702710
if(!sub_size.has_value())
703711
{

src/ansi-c/expr2c.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,12 +1863,13 @@ std::string expr2ct::convert_constant(
18631863
if(src.find(ID_C_c_sizeof_type).is_not_nil() &&
18641864
sizeof_nesting==0)
18651865
{
1866-
const exprt sizeof_expr = build_sizeof_expr(to_constant_expr(src), ns);
1866+
const auto sizeof_expr_opt =
1867+
build_sizeof_expr(to_constant_expr(src), ns);
18671868

1868-
if(sizeof_expr.is_not_nil())
1869+
if(sizeof_expr_opt.has_value())
18691870
{
18701871
++sizeof_nesting;
1871-
dest=convert(sizeof_expr)+" /*"+dest+"*/ ";
1872+
dest = convert(sizeof_expr_opt.value()) + " /*" + dest + "*/ ";
18721873
--sizeof_nesting;
18731874
}
18741875
}

src/cpp/cpp_typecheck_expr.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -823,10 +823,14 @@ void cpp_typecheckt::typecheck_expr_new(exprt &expr)
823823

824824
// we add the size of the object for convenience of the
825825
// runtime library
826+
auto size_of_opt = size_of_expr(expr.type().subtype(), *this);
826827

827-
exprt &sizeof_expr=static_cast<exprt &>(expr.add(ID_sizeof));
828-
sizeof_expr=size_of_expr(expr.type().subtype(), *this);
829-
sizeof_expr.add(ID_C_c_sizeof_type)=expr.type().subtype();
828+
if(size_of_opt.has_value())
829+
{
830+
auto &sizeof_expr = static_cast<exprt &>(expr.add(ID_sizeof));
831+
sizeof_expr = size_of_opt.value();
832+
sizeof_expr.add(ID_C_c_sizeof_type) = expr.type().subtype();
833+
}
830834
}
831835

832836
static exprt collect_comma_expression(const exprt &src)

src/cpp/cpp_typecheck_initializer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,10 @@ void cpp_typecheckt::zero_initializer(
266266
if(component.type().id()==ID_code)
267267
continue;
268268

269-
exprt component_size=size_of_expr(component.type(), *this);
269+
auto component_size_opt = size_of_expr(component.type(), *this);
270270

271-
const auto size_int = numeric_cast<mp_integer>(component_size);
271+
const auto size_int =
272+
numeric_cast<mp_integer>(component_size_opt.value_or(nil_exprt()));
272273
if(size_int.has_value())
273274
{
274275
if(*size_int > max_comp_size)

src/goto-programs/mm_io.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ void mm_io(
6565

6666
const typet &pt=ct.parameters()[0].type();
6767
const typet &st=ct.parameters()[1].type();
68-
exprt size=size_of_expr(d.type(), ns);
68+
auto size_opt = size_of_expr(d.type(), ns);
69+
CHECK_RETURN(size_opt.has_value());
6970
const code_function_callt fc(
7071
mm_io_r,
71-
{typecast_exprt(d.pointer(), pt), typecast_exprt(size, st)});
72+
{typecast_exprt(d.pointer(), pt),
73+
typecast_exprt(size_opt.value(), st)});
7274
goto_function.body.insert_before_swap(it);
7375
*it = goto_programt::make_function_call(fc, source_location);
7476
it++;
@@ -85,11 +87,12 @@ void mm_io(
8587
const typet &pt=ct.parameters()[0].type();
8688
const typet &st=ct.parameters()[1].type();
8789
const typet &vt=ct.parameters()[2].type();
88-
exprt size=size_of_expr(d.type(), ns);
90+
auto size_opt = size_of_expr(d.type(), ns);
91+
CHECK_RETURN(size_opt.has_value());
8992
const code_function_callt fc(
9093
mm_io_w,
9194
{typecast_exprt(d.pointer(), pt),
92-
typecast_exprt(size, st),
95+
typecast_exprt(size_opt.value(), st),
9396
typecast_exprt(a.rhs(), vt)});
9497
goto_function.body.insert_before_swap(it);
9598
*it = goto_programt::make_function_call(fc, source_location);

src/goto-symex/symex_clean_expr.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ process_array_expr(exprt &expr, bool do_simplify, const namespacet &ns)
7979
{
8080
if(expr.type().id() != ID_array)
8181
{
82-
exprt array_size = size_of_expr(expr.type(), ns);
82+
auto array_size = size_of_expr(expr.type(), ns);
83+
CHECK_RETURN(array_size.has_value());
8384
if(do_simplify)
84-
simplify(array_size, ns);
85-
expr =
86-
byte_extract_exprt(
87-
byte_extract_id(),
88-
expr,
89-
from_integer(0, index_type()),
90-
array_typet(char_type(), array_size));
85+
simplify(array_size.value(), ns);
86+
expr = byte_extract_exprt(
87+
byte_extract_id(),
88+
expr,
89+
from_integer(0, index_type()),
90+
array_typet(char_type(), array_size.value()));
9191
}
9292

9393
// given an array type T[N], i.e., an array of N elements of type T, and a
@@ -99,8 +99,10 @@ process_array_expr(exprt &expr, bool do_simplify, const namespacet &ns)
9999

100100
exprt new_offset =
101101
typecast_exprt::conditional_cast(ode.offset(), array_size_type);
102+
auto subtype_size_opt = size_of_expr(subtype, ns);
103+
CHECK_RETURN(subtype_size_opt.has_value());
102104
exprt subtype_size = typecast_exprt::conditional_cast(
103-
size_of_expr(subtype, ns), array_size_type);
105+
subtype_size_opt.value(), array_size_type);
104106
new_offset = div_exprt(new_offset, subtype_size);
105107
minus_exprt new_size(prev_array_type.size(), new_offset);
106108
if(do_simplify)

src/goto-symex/symex_other.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,14 @@ void goto_symext::symex_other(
205205
// byte array
206206
if(array_expr.type().id() != ID_array)
207207
{
208-
exprt array_size = size_of_expr(array_expr.type(), ns);
209-
do_simplify(array_size);
210-
array_expr =
211-
byte_extract_exprt(
212-
byte_extract_id(),
213-
array_expr,
214-
from_integer(0, index_type()),
215-
array_typet(char_type(), array_size));
208+
auto array_size = size_of_expr(array_expr.type(), ns);
209+
CHECK_RETURN(array_size.has_value());
210+
do_simplify(array_size.value());
211+
array_expr = byte_extract_exprt(
212+
byte_extract_id(),
213+
array_expr,
214+
from_integer(0, index_type()),
215+
array_typet(char_type(), array_size.value()));
216216
}
217217

218218
const array_typet &array_type = to_array_type(array_expr.type());

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,15 +440,15 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
440440
else
441441
{
442442
// try to build a member/index expression - do not use byte_extract
443-
exprt subexpr = get_subexpression_at_offset(
443+
auto subexpr = get_subexpression_at_offset(
444444
root_object_subexpression, o.offset(), dereference_type, ns);
445-
if(subexpr.is_not_nil())
446-
simplify(subexpr, ns);
447-
if(subexpr.is_not_nil() && subexpr.id() != byte_extract_id())
445+
if(subexpr.has_value())
446+
simplify(subexpr.value(), ns);
447+
if(subexpr.has_value() && subexpr.value().id() != byte_extract_id())
448448
{
449449
// Successfully found a member, array index, or combination thereof
450450
// that matches the desired type and offset:
451-
result.value = subexpr;
451+
result.value = subexpr.value();
452452
return result;
453453
}
454454

0 commit comments

Comments
 (0)