@@ -1101,325 +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,
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
-
1423
1104
// / Used to provide our own implementation of the java.lang.Object.getClass()
1424
1105
// / function.
1425
1106
// / \param type: type of the function called
0 commit comments