Skip to content

Commit 188e5d5

Browse files
Remove code that is now unreachable
To use the builtin format function, the java entry point is now CProverString.format, so we can remove the legacy code which was handling String.format directly.
1 parent 6280b4d commit 188e5d5

File tree

3 files changed

+16
-375
lines changed

3 files changed

+16
-375
lines changed

jbmc/src/java_bytecode/java_string_library_preprocess.cpp

Lines changed: 0 additions & 319 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,325 +1101,6 @@ code_blockt java_string_library_preprocesst::make_assign_function_from_call(
11011101
function_id, type, loc, symbol_table, false);
11021102
}
11031103

1104-
/// Adds to the code an assignment of the form
1105-
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1106-
/// type_name tmp_type_name
1107-
/// tmp_type_name = ((Classname*)arg_i)->value
1108-
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1109-
/// and returns `tmp_typename`.
1110-
/// In case the class corresponding to `type_name` is not available in
1111-
/// `symbol_table`, the variable is declared but not assigned.
1112-
/// Used to access the values of the arguments of `String.format`.
1113-
/// \param object: an expression representing a reference to an object
1114-
/// \param type_name: name of the corresponding primitive type, this can be
1115-
/// one of the following: ID_boolean, ID_char, ID_byte, ID_short, ID_int,
1116-
/// ID_long, ID_float, ID_double, ID_void
1117-
/// \param loc: a location in the source
1118-
/// \param function_id: the name of the function
1119-
/// \param symbol_table: the symbol table
1120-
/// \param code: code block to which we are adding some assignments
1121-
/// \return An expression containing a symbol `tmp_type_name` where `type_name`
1122-
/// is the given argument (ie. boolean, char etc.). Which represents the
1123-
/// primitive value contained in the given object.
1124-
optionalt<symbol_exprt>
1125-
java_string_library_preprocesst::get_primitive_value_of_object(
1126-
const exprt &object,
1127-
irep_idt type_name,
1128-
const source_locationt &loc,
1129-
const irep_idt &function_id,
1130-
symbol_table_baset &symbol_table,
1131-
code_blockt &code)
1132-
{
1133-
optionalt<struct_tag_typet> object_type;
1134-
1135-
typet value_type;
1136-
if(type_name==ID_boolean)
1137-
{
1138-
value_type=java_boolean_type();
1139-
object_type = struct_tag_typet("java::java.lang.Boolean");
1140-
}
1141-
else if(type_name==ID_char)
1142-
{
1143-
value_type=java_char_type();
1144-
object_type = struct_tag_typet("java::java.lang.Character");
1145-
}
1146-
else if(type_name==ID_byte)
1147-
{
1148-
value_type=java_byte_type();
1149-
object_type = struct_tag_typet("java::java.lang.Byte");
1150-
}
1151-
else if(type_name==ID_short)
1152-
{
1153-
value_type=java_short_type();
1154-
object_type = struct_tag_typet("java::java.lang.Short");
1155-
}
1156-
else if(type_name==ID_int)
1157-
{
1158-
value_type=java_int_type();
1159-
object_type = struct_tag_typet("java::java.lang.Integer");
1160-
}
1161-
else if(type_name==ID_long)
1162-
{
1163-
value_type=java_long_type();
1164-
object_type = struct_tag_typet("java::java.lang.Long");
1165-
}
1166-
else if(type_name==ID_float)
1167-
{
1168-
value_type=java_float_type();
1169-
object_type = struct_tag_typet("java::java.lang.Float");
1170-
}
1171-
else if(type_name==ID_double)
1172-
{
1173-
value_type=java_double_type();
1174-
object_type = struct_tag_typet("java::java.lang.Double");
1175-
}
1176-
else if(type_name==ID_void)
1177-
return {};
1178-
else
1179-
UNREACHABLE;
1180-
1181-
DATA_INVARIANT(object_type.has_value(), "must have symbol for primitive");
1182-
1183-
// declare tmp_type_name to hold the value
1184-
const std::string aux_name = "tmp_" + id2string(type_name);
1185-
const symbolt &symbol =
1186-
fresh_java_symbol(value_type, aux_name, loc, function_id, symbol_table);
1187-
const auto value = symbol.symbol_expr();
1188-
1189-
// Check that the type of the object is in the symbol table,
1190-
// otherwise there is no safe way of finding its value.
1191-
if(
1192-
const auto maybe_symbol =
1193-
symbol_table.lookup(object_type->get_identifier()))
1194-
{
1195-
const struct_typet &struct_type = to_struct_type(maybe_symbol->type);
1196-
// Check that the type has a value field
1197-
const struct_union_typet::componentt &value_comp =
1198-
struct_type.get_component("value");
1199-
if(!value_comp.is_nil())
1200-
{
1201-
const pointer_typet struct_pointer_type = pointer_type(struct_type);
1202-
dereference_exprt deref{typecast_exprt(object, struct_pointer_type),
1203-
struct_pointer_type.subtype()};
1204-
const member_exprt deref_value{
1205-
std::move(deref), value_comp.get_name(), value_comp.type()};
1206-
code.add(code_assignt(value, deref_value), loc);
1207-
return value;
1208-
}
1209-
}
1210-
1211-
warning() << object_type->get_identifier()
1212-
<< " not available to format function" << eom;
1213-
code.add(code_declt(value), loc);
1214-
return value;
1215-
}
1216-
1217-
/// Helper for format function. Returns the expression:
1218-
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1219-
/// *((void**)(argv->data)+index )
1220-
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1221-
/// which corresponds to the object at position `index` in `argv`.
1222-
/// \param argv: reference to an array of references
1223-
/// \param index: index of the desired object
1224-
/// \return An expression representing the object at position `index` of `argv`.
1225-
dereference_exprt java_string_library_preprocesst::get_object_at_index(
1226-
const exprt &argv,
1227-
std::size_t index)
1228-
{
1229-
const dereference_exprt deref_objs{argv, argv.type().subtype()};
1230-
const pointer_typet empty_pointer = pointer_type(java_void_type());
1231-
const pointer_typet pointer_of_pointer = pointer_type(empty_pointer);
1232-
const member_exprt data_member{deref_objs, "data", pointer_of_pointer};
1233-
const plus_exprt data_pointer_plus_index{
1234-
data_member, from_integer(index, java_int_type()), data_member.type()};
1235-
return dereference_exprt{data_pointer_plus_index,
1236-
data_pointer_plus_index.type().subtype()};
1237-
}
1238-
1239-
/// Helper for format function. Adds code:
1240-
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1241-
/// string_expr arg_i_string_expr;
1242-
/// int tmp_int;
1243-
/// float tmp_float;
1244-
/// char tmp_char;
1245-
/// boolean tmp_boolean;
1246-
/// Object* arg_i=get_object_at_index(argv, index)
1247-
/// if(arg_i.@class_identifier=="java::java.lang.String")
1248-
/// {
1249-
/// arg_i_string_expr = (string_expr)((String*)arg_i_as_string)
1250-
/// }
1251-
/// tmp_int=((Integer)arg_i)->value
1252-
/// tmp_float=((Float)arg_i)->value
1253-
/// tmp_char=((Char)arg_i)->value
1254-
/// tmp_boolean=((Boolean)arg_i)->value
1255-
/// arg_i_struct = { string_expr=arg_i_string_expr;
1256-
/// integer=tmp_int; float=tmp_float; char=tmp_char; boolean=tmp_boolean}
1257-
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1258-
/// and returns `arg_i_struct`.
1259-
///
1260-
/// TODO: date_time and hash code are not implemented
1261-
/// \param argv: reference to an array of references
1262-
/// \param index: index of the desired argument
1263-
/// \param structured_type: type for arguments of the internal format function
1264-
/// \param loc: a location in the source
1265-
/// \param function_id: function the generated expression will be used in
1266-
/// \param symbol_table: the symbol table
1267-
/// \param code: code block to which we are adding some assignments
1268-
/// \return An expression of type `structured_type` representing the possible
1269-
/// values of the argument at position `index` of `argv`.
1270-
struct_exprt java_string_library_preprocesst::make_argument_for_format(
1271-
const exprt &argv,
1272-
std::size_t index,
1273-
const struct_typet &structured_type,
1274-
const source_locationt &loc,
1275-
const irep_idt &function_id,
1276-
symbol_table_baset &symbol_table,
1277-
code_blockt &code)
1278-
{
1279-
// Declarations of the fields of arg_i_struct
1280-
// arg_i_struct is { arg_i_string_expr, tmp_int, tmp_char, ... }
1281-
struct_exprt arg_i_struct({}, structured_type);
1282-
std::list<exprt> field_exprs;
1283-
for(const auto & comp : structured_type.components())
1284-
{
1285-
const irep_idt &name=comp.get_name();
1286-
const typet &type=comp.type();
1287-
exprt field_expr;
1288-
if(name!="string_expr")
1289-
{
1290-
std::string tmp_name="tmp_"+id2string(name);
1291-
const symbolt &field_symbol =
1292-
fresh_java_symbol(type, tmp_name, loc, function_id, symbol_table);
1293-
auto field_symbol_expr = field_symbol.symbol_expr();
1294-
field_expr = field_symbol_expr;
1295-
code.add(code_declt(field_symbol_expr), loc);
1296-
}
1297-
else
1298-
field_expr =
1299-
make_nondet_string_expr(loc, function_id, symbol_table, code);
1300-
1301-
field_exprs.push_back(field_expr);
1302-
arg_i_struct.copy_to_operands(field_expr);
1303-
}
1304-
1305-
// arg_i = argv[index]
1306-
const exprt obj = get_object_at_index(argv, index);
1307-
const symbolt &object_symbol = fresh_java_symbol(
1308-
obj.type(), "tmp_format_obj", loc, function_id, symbol_table);
1309-
const symbol_exprt arg_i = object_symbol.symbol_expr();
1310-
1311-
allocate_objectst allocate_objects(ID_java, loc, function_id, symbol_table);
1312-
1313-
code_blockt tmp;
1314-
allocate_objects.allocate_dynamic_object(tmp, arg_i, arg_i.type().subtype());
1315-
allocate_objects.declare_created_symbols(code);
1316-
code.append(tmp);
1317-
1318-
code.add(code_assignt(arg_i, obj), loc);
1319-
code.add(
1320-
code_assumet(
1321-
not_exprt(
1322-
equal_exprt(arg_i, null_pointer_exprt(to_pointer_type(arg_i.type()))))),
1323-
loc);
1324-
1325-
code_blockt code_not_null;
1326-
1327-
// Assigning all the fields of arg_i_struct
1328-
for(const auto &comp : structured_type.components())
1329-
{
1330-
const irep_idt &name=comp.get_name();
1331-
exprt field_expr=field_exprs.front();
1332-
field_exprs.pop_front();
1333-
1334-
if(name=="string_expr")
1335-
{
1336-
const pointer_typet string_pointer =
1337-
java_reference_type(struct_tag_typet("java::java.lang.String"));
1338-
const typecast_exprt arg_i_as_string{arg_i, string_pointer};
1339-
code_assign_java_string_to_string_expr(
1340-
to_string_expr(field_expr),
1341-
arg_i_as_string,
1342-
loc,
1343-
symbol_table,
1344-
code_not_null);
1345-
}
1346-
else if(name==ID_int || name==ID_float || name==ID_char || name==ID_boolean)
1347-
{
1348-
const auto value = get_primitive_value_of_object(
1349-
arg_i, name, loc, function_id, symbol_table, code_not_null);
1350-
if(value.has_value())
1351-
code_not_null.add(code_assignt(field_expr, *value), loc);
1352-
else
1353-
code_not_null.add(code_assignt(field_expr, nil_exprt()), loc);
1354-
}
1355-
else
1356-
{
1357-
// TODO: date_time and hash_code not implemented
1358-
}
1359-
}
1360-
1361-
code.add(code_not_null, loc);
1362-
return arg_i_struct;
1363-
}
1364-
1365-
/// Used to provide code for the Java String.format function.
1366-
///
1367-
/// TODO: date_time and hash code are not implemented, and we set a limit of
1368-
/// 10 arguments
1369-
/// \param type: type of the function call
1370-
/// \param loc: location in the program_invocation_name
1371-
/// \param function_id: function the generated code will be used in
1372-
/// \param symbol_table: symbol table
1373-
/// \return Code implementing the Java String.format function. Since the exact
1374-
/// class of the arguments is not known, we give as argument to the internal
1375-
// format function a structure containing the different possible types.
1376-
code_blockt java_string_library_preprocesst::make_string_format_code(
1377-
const java_method_typet &type,
1378-
const source_locationt &loc,
1379-
const irep_idt &function_id,
1380-
symbol_table_baset &symbol_table)
1381-
{
1382-
PRECONDITION(type.parameters().size()==2);
1383-
code_blockt code;
1384-
exprt::operandst args =
1385-
process_parameters(type.parameters(), loc, function_id, symbol_table, code);
1386-
INVARIANT(args.size()==2, "String.format should have two arguments");
1387-
1388-
// The argument can be:
1389-
// a string, an integer, a floating point, a character, a boolean,
1390-
// an object of which we take the hash code, or a date/time
1391-
struct_typet structured_type({{"string_expr", refined_string_type},
1392-
{ID_int, java_int_type()},
1393-
{ID_float, java_float_type()},
1394-
{ID_char, java_char_type()},
1395-
{ID_boolean, java_boolean_type()},
1396-
// TODO: hash_code not implemented for now
1397-
{"hashcode", java_int_type()},
1398-
// TODO: date_time type not implemented for now
1399-
{"date_time", java_int_type()}});
1400-
structured_type.set_tag(CPROVER_PREFIX "string_formatter_variant");
1401-
1402-
// We will process arguments so that each is converted to a `struct_exprt`
1403-
// containing each possible type used in format specifiers.
1404-
std::vector<exprt> processed_args;
1405-
processed_args.push_back(args[0]);
1406-
for(std::size_t i=0; i<MAX_FORMAT_ARGS; ++i)
1407-
processed_args.push_back(
1408-
make_argument_for_format(
1409-
args[1], i, structured_type, loc, function_id, symbol_table, code));
1410-
1411-
const refined_string_exprt string_expr = string_expr_of_function(
1412-
ID_cprover_string_format_func, processed_args, loc, symbol_table, code);
1413-
const exprt java_string = allocate_fresh_string(
1414-
type.return_type(), loc, function_id, symbol_table, code);
1415-
code.add(
1416-
code_assign_string_expr_to_java_string(
1417-
java_string, string_expr, symbol_table, true),
1418-
loc);
1419-
code.add(code_returnt(java_string), loc);
1420-
return code;
1421-
}
1422-
14231104
/// Used to provide our own implementation of the java.lang.Object.getClass()
14241105
/// function.
14251106
/// \param type: type of the function called

jbmc/src/java_bytecode/java_string_library_preprocess.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,6 @@ class java_string_library_preprocesst:public messaget
151151
const irep_idt &function_id,
152152
symbol_table_baset &symbol_table);
153153

154-
code_blockt make_string_format_code(
155-
const java_method_typet &type,
156-
const source_locationt &loc,
157-
const irep_idt &function_id,
158-
symbol_table_baset &symbol_table);
159-
160154
code_blockt make_copy_string_code(
161155
const java_method_typet &type,
162156
const source_locationt &loc,
@@ -313,25 +307,6 @@ class java_string_library_preprocesst:public messaget
313307
const java_method_typet &type,
314308
const source_locationt &loc,
315309
symbol_table_baset &symbol_table);
316-
317-
struct_exprt make_argument_for_format(
318-
const exprt &argv,
319-
std::size_t index,
320-
const struct_typet &structured_type,
321-
const source_locationt &loc,
322-
const irep_idt &function_id,
323-
symbol_table_baset &symbol_table,
324-
code_blockt &code);
325-
326-
optionalt<symbol_exprt> get_primitive_value_of_object(
327-
const exprt &object,
328-
irep_idt type_name,
329-
const source_locationt &loc,
330-
const irep_idt &function_id,
331-
symbol_table_baset &symbol_table,
332-
code_blockt &code);
333-
334-
dereference_exprt get_object_at_index(const exprt &argv, std::size_t index);
335310
};
336311

337312
exprt make_nondet_infinite_char_array(

0 commit comments

Comments
 (0)