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