Skip to content

Commit ebfb529

Browse files
committed
numeric_cast_v(expr) now requires constant_expr
This is follow-up from a discussion on PR #3998, and a comment by @tautschnig. This function always fails, with an exception, when given anything but a constant_exprt. This change means that the caller must do the type conversion. The benefit is to make the caller more aware of the requirement that this must be a constant, and to make the caller handle the error appropriately (with an user-friendly error message) in case this is not possible. The disadvantage is additional code at the call site.
1 parent 2376058 commit ebfb529

35 files changed

+227
-144
lines changed

jbmc/src/java_bytecode/java_bytecode_concurrency_instrumentation.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ static const std::string get_thread_block_identifier(
8686
{
8787
PRECONDITION(f_code.arguments().size() == 1);
8888
const exprt &expr = f_code.arguments()[0];
89-
const mp_integer lbl_id = numeric_cast_v<mp_integer>(expr.op0());
89+
const mp_integer lbl_id =
90+
numeric_cast_v<mp_integer>(to_constant_expr(expr.op0()));
9091
return integer2string(lbl_id);
9192
}
9293

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ exprt java_bytecode_convert_methodt::variable(
208208
java_bytecode_convert_methodt::variable_cast_argumentt do_cast)
209209
{
210210
typet t=java_type_from_char(type_char);
211-
const std::size_t number_int = numeric_cast_v<std::size_t>(arg);
211+
const std::size_t number_int =
212+
numeric_cast_v<std::size_t>(to_constant_expr(arg));
212213
variablest &var_list=variables[number_int];
213214

214215
// search variable in list for correct frame / address if necessary
@@ -1343,15 +1344,17 @@ code_blockt java_bytecode_convert_methodt::convert_instructions(
13431344
else if(statement=="goto" || statement=="goto_w")
13441345
{
13451346
PRECONDITION(op.empty() && results.empty());
1346-
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
1347+
const mp_integer number =
1348+
numeric_cast_v<mp_integer>(to_constant_expr(arg0));
13471349
code_gotot code_goto(label(integer2string(number)));
13481350
c=code_goto;
13491351
}
13501352
else if(statement=="jsr" || statement=="jsr_w")
13511353
{
13521354
// As 'goto', except we must also push the subroutine return address:
13531355
PRECONDITION(op.empty() && results.size() == 1);
1354-
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
1356+
const mp_integer number =
1357+
numeric_cast_v<mp_integer>(to_constant_expr(arg0));
13551358
code_gotot code_goto(label(integer2string(number)));
13561359
c=code_goto;
13571360
results[0]=
@@ -1378,7 +1381,7 @@ code_blockt java_bytecode_convert_methodt::convert_instructions(
13781381
else if(statement==patternt("?const"))
13791382
{
13801383
assert(results.size()==1);
1381-
results = convert_const(statement, arg0, results);
1384+
results = convert_const(statement, to_constant_expr(arg0), results);
13821385
}
13831386
else if(statement==patternt("?ipush"))
13841387
{
@@ -1391,7 +1394,8 @@ code_blockt java_bytecode_convert_methodt::convert_instructions(
13911394
else if(statement==patternt("if_?cmp??"))
13921395
{
13931396
PRECONDITION(op.size() == 2 && results.empty());
1394-
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
1397+
const mp_integer number =
1398+
numeric_cast_v<mp_integer>(to_constant_expr(arg0));
13951399
c = convert_if_cmp(
13961400
address_map, statement, op, number, i_it->source_location);
13971401
}
@@ -1408,19 +1412,22 @@ code_blockt java_bytecode_convert_methodt::convert_instructions(
14081412

14091413
INVARIANT(!id.empty(), "unexpected bytecode-if");
14101414
PRECONDITION(op.size() == 1 && results.empty());
1411-
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
1415+
const mp_integer number =
1416+
numeric_cast_v<mp_integer>(to_constant_expr(arg0));
14121417
c = convert_if(address_map, op, id, number, i_it->source_location);
14131418
}
14141419
else if(statement==patternt("ifnonnull"))
14151420
{
14161421
PRECONDITION(op.size() == 1 && results.empty());
1417-
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
1422+
const mp_integer number =
1423+
numeric_cast_v<mp_integer>(to_constant_expr(arg0));
14181424
c = convert_ifnonull(address_map, op, number, i_it->source_location);
14191425
}
14201426
else if(statement==patternt("ifnull"))
14211427
{
14221428
PRECONDITION(op.size() == 1 && results.empty());
1423-
const mp_integer number = numeric_cast_v<mp_integer>(arg0);
1429+
const mp_integer number =
1430+
numeric_cast_v<mp_integer>(to_constant_expr(arg0));
14241431
c = convert_ifnull(address_map, op, number, i_it->source_location);
14251432
}
14261433
else if(statement=="iinc")
@@ -1615,7 +1622,8 @@ code_blockt java_bytecode_convert_methodt::convert_instructions(
16151622
{
16161623
// The first argument is the type, the second argument is the number of
16171624
// dimensions. The size of each dimension is on the stack.
1618-
const std::size_t dimension = numeric_cast_v<std::size_t>(arg1);
1625+
const std::size_t dimension =
1626+
numeric_cast_v<std::size_t>(to_constant_expr(arg1));
16191627

16201628
op=pop(dimension);
16211629
assert(results.size()==1);
@@ -1939,7 +1947,8 @@ code_switcht java_bytecode_convert_methodt::convert_switch(
19391947
{
19401948
if(is_label)
19411949
{
1942-
const mp_integer number = numeric_cast_v<mp_integer>(*a_it);
1950+
const mp_integer number =
1951+
numeric_cast_v<mp_integer>(to_constant_expr(*a_it));
19431952
// The switch case does not contain any code, it just branches via a GOTO
19441953
// to the jump target of the tableswitch/lookupswitch case at
19451954
// hand. Therefore we consider this code to belong to the source bytecode
@@ -2048,7 +2057,7 @@ void java_bytecode_convert_methodt::convert_dup2_x2(
20482057

20492058
exprt::operandst &java_bytecode_convert_methodt::convert_const(
20502059
const irep_idt &statement,
2051-
const exprt &arg0,
2060+
const constant_exprt &arg0,
20522061
exprt::operandst &results) const
20532062
{
20542063
const char type_char = statement[0];
@@ -2068,7 +2077,7 @@ exprt::operandst &java_bytecode_convert_methodt::convert_const(
20682077
value.from_integer(number);
20692078
}
20702079
else
2071-
value.from_expr(to_constant_expr(arg0));
2080+
value.from_expr(arg0);
20722081

20732082
results[0] = value.to_expr();
20742083
}

jbmc/src/java_bytecode/java_bytecode_convert_method_class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ class java_bytecode_convert_methodt:public messaget
487487

488488
exprt::operandst &convert_const(
489489
const irep_idt &statement,
490-
const exprt &arg0,
490+
const constant_exprt &arg0,
491491
exprt::operandst &results) const;
492492

493493
void convert_dup2_x2(exprt::operandst &op, exprt::operandst &results);

jbmc/unit/solvers/strings/string_constraint_instantiation/instantiate_not_contains.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ refined_string_exprt make_refined_string_exprt(const array_string_exprt &arr)
9898
/// \return the corresponding index set
9999
std::set<exprt> full_index_set(const array_string_exprt &s)
100100
{
101-
const mp_integer n = numeric_cast_v<mp_integer>(s.length());
101+
const mp_integer n = numeric_cast_v<mp_integer>(to_constant_expr(s.length()));
102102
std::set<exprt> ret;
103103
for(mp_integer i = 0; i < n; ++i)
104104
ret.insert(from_integer(i));

src/analyses/interval_domain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ void interval_domaint::assume_rec(
254254

255255
if(is_int(lhs.type()) && is_int(rhs.type()))
256256
{
257-
mp_integer tmp = numeric_cast_v<mp_integer>(rhs);
257+
mp_integer tmp = numeric_cast_v<mp_integer>(to_constant_expr(rhs));
258258
if(id==ID_lt)
259259
--tmp;
260260
integer_intervalt &ii=int_map[lhs_identifier];
@@ -279,7 +279,7 @@ void interval_domaint::assume_rec(
279279

280280
if(is_int(lhs.type()) && is_int(rhs.type()))
281281
{
282-
mp_integer tmp = numeric_cast_v<mp_integer>(lhs);
282+
mp_integer tmp = numeric_cast_v<mp_integer>(to_constant_expr(lhs));
283283
if(id==ID_lt)
284284
++tmp;
285285
integer_intervalt &ii=int_map[rhs_identifier];

src/analyses/invariant_set.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,8 @@ exprt invariant_sett::get_constant(const exprt &expr) const
858858

859859
if(e.is_constant())
860860
{
861-
const mp_integer value = numeric_cast_v<mp_integer>(e);
861+
const mp_integer value =
862+
numeric_cast_v<mp_integer>(to_constant_expr(e));
862863

863864
if(expr.type().id()==ID_pointer)
864865
{

src/ansi-c/c_nondet_symbol_factory.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ void symbol_factoryt::gen_nondet_array_init(
155155
const recursion_sett &recursion_set)
156156
{
157157
auto const &array_type = to_array_type(expr.type());
158-
auto const array_size = numeric_cast_v<size_t>(array_type.size());
158+
const auto &size = array_type.size();
159+
PRECONDITION(size.id() == ID_constant);
160+
auto const array_size = numeric_cast_v<size_t>(to_constant_expr(size));
159161
DATA_INVARIANT(array_size > 0, "Arrays should have positive size");
160162
for(size_t index = 0; index < array_size; ++index)
161163
{

src/ansi-c/expr2c.cpp

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -578,34 +578,39 @@ std::string expr2ct::convert_rec(
578578
else if(src.id()==ID_vector)
579579
{
580580
const vector_typet &vector_type=to_vector_type(src);
581+
const auto &size = vector_type.size();
581582

582-
const mp_integer size_int = numeric_cast_v<mp_integer>(vector_type.size());
583-
std::string dest="__gcc_v"+integer2string(size_int);
584-
585-
std::string tmp=convert(vector_type.subtype());
586-
587-
if(tmp=="signed char" || tmp=="char")
588-
dest+="qi";
589-
else if(tmp=="signed short int")
590-
dest+="hi";
591-
else if(tmp=="signed int")
592-
dest+="si";
593-
else if(tmp=="signed long long int")
594-
dest+="di";
595-
else if(tmp=="float")
596-
dest+="sf";
597-
else if(tmp=="double")
598-
dest+="df";
599-
else
583+
if(size.id() == ID_constant)
600584
{
601-
const std::string subtype=convert(vector_type.subtype());
602-
dest=subtype;
603-
dest+=" __attribute__((vector_size (";
604-
dest+=convert(vector_type.size());
605-
dest+="*sizeof("+subtype+"))))";
606-
}
585+
const mp_integer size_int =
586+
numeric_cast_v<mp_integer>(to_constant_expr(size));
587+
std::string dest = "__gcc_v" + integer2string(size_int);
588+
589+
std::string tmp = convert(vector_type.subtype());
590+
591+
if(tmp == "signed char" || tmp == "char")
592+
dest += "qi";
593+
else if(tmp == "signed short int")
594+
dest += "hi";
595+
else if(tmp == "signed int")
596+
dest += "si";
597+
else if(tmp == "signed long long int")
598+
dest += "di";
599+
else if(tmp == "float")
600+
dest += "sf";
601+
else if(tmp == "double")
602+
dest += "df";
603+
else
604+
{
605+
const std::string subtype = convert(vector_type.subtype());
606+
dest = subtype;
607+
dest += " __attribute__((vector_size (";
608+
dest += convert(vector_type.size());
609+
dest += "*sizeof(" + subtype + "))))";
610+
}
607611

608-
return q+dest+d;
612+
return q + dest + d;
613+
}
609614
}
610615
else if(src.id()==ID_gcc_builtin_va_list)
611616
{
@@ -2170,7 +2175,7 @@ std::string expr2ct::convert_array(
21702175
if(it==--src.operands().end())
21712176
break;
21722177

2173-
const unsigned int ch = numeric_cast_v<unsigned>(*it);
2178+
const unsigned int ch = numeric_cast_v<unsigned>(to_constant_expr(*it));
21742179

21752180
if(last_was_hex)
21762181
{

src/cpp/cpp_typecheck_initializer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ void cpp_typecheckt::zero_initializer(
234234
if(size_expr.id()==ID_infinity)
235235
return; // don't initialize
236236

237-
const mp_integer size = numeric_cast_v<mp_integer>(size_expr);
237+
const mp_integer size =
238+
numeric_cast_v<mp_integer>(to_constant_expr(size_expr));
238239
CHECK_RETURN(size>=0);
239240

240241
exprt::operandst empty_operands;

src/goto-instrument/accelerate/polynomial.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void polynomialt::from_expr(const exprt &expr)
139139
else if(expr.id()==ID_constant)
140140
{
141141
monomialt monomial;
142-
monomial.coeff = numeric_cast_v<int>(expr);
142+
monomial.coeff = numeric_cast_v<int>(to_constant_expr(expr));
143143

144144
monomials.push_back(monomial);
145145
}

0 commit comments

Comments
 (0)