@@ -186,6 +186,11 @@ static bool check_format_string(std::string s)
186
186
}
187
187
#endif
188
188
189
+ static exprt format_arg_from_string (
190
+ const array_string_exprt &string,
191
+ const irep_idt &id,
192
+ array_poolt &array_pool);
193
+
189
194
// / Helper function for parsing format strings.
190
195
// / This follows the implementation in openJDK of the java.util.Formatter class:
191
196
// / http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/9b8c96f96a0f/src/share/classes/java/util/Formatter.java#l2660
@@ -272,7 +277,7 @@ static std::pair<array_string_exprt, string_constraintst>
272
277
add_axioms_for_format_specifier (
273
278
symbol_generatort &fresh_symbol,
274
279
const format_specifiert &fs,
275
- const std::function<exprt( const irep_idt &)> &get_arg ,
280
+ const array_string_exprt &string_arg ,
276
281
const typet &index_type,
277
282
const typet &char_type,
278
283
array_poolt &array_pool,
@@ -285,24 +290,41 @@ add_axioms_for_format_specifier(
285
290
switch (fs.conversion )
286
291
{
287
292
case format_specifiert::DECIMAL_INTEGER:
288
- return_code =
289
- add_axioms_for_string_of_int (res, get_arg (ID_int), 0 , ns, array_pool);
293
+ return_code = add_axioms_for_string_of_int (
294
+ res,
295
+ format_arg_from_string (string_arg, ID_int, array_pool),
296
+ 0 ,
297
+ ns,
298
+ array_pool);
290
299
return {res, std::move (return_code.second )};
291
300
case format_specifiert::HEXADECIMAL_INTEGER:
292
301
return_code = add_axioms_for_string_of_int_with_radix (
293
- res, get_arg (ID_int), from_integer (16 , index_type), 16 , ns, array_pool);
302
+ res,
303
+ format_arg_from_string (string_arg, ID_int, array_pool),
304
+ from_integer (16 , index_type),
305
+ 16 ,
306
+ ns,
307
+ array_pool);
294
308
return {res, std::move (return_code.second )};
295
309
case format_specifiert::SCIENTIFIC:
296
310
return_code = add_axioms_from_float_scientific_notation (
297
- fresh_symbol, res, get_arg (ID_float), array_pool, ns);
311
+ fresh_symbol,
312
+ res,
313
+ format_arg_from_string (string_arg, ID_float, array_pool),
314
+ array_pool,
315
+ ns);
298
316
return {res, std::move (return_code.second )};
299
317
case format_specifiert::DECIMAL_FLOAT:
300
318
return_code = add_axioms_for_string_of_float (
301
- fresh_symbol, res, get_arg (ID_float), array_pool, ns);
319
+ fresh_symbol,
320
+ res,
321
+ format_arg_from_string (string_arg, ID_float, array_pool),
322
+ array_pool,
323
+ ns);
302
324
return {res, std::move (return_code.second )};
303
325
case format_specifiert::CHARACTER:
304
326
{
305
- exprt arg_string = get_arg ( ID_char);
327
+ exprt arg_string = format_arg_from_string (string_arg, ID_char, array_pool );
306
328
array_string_exprt &string_expr = to_array_string_expr (arg_string);
307
329
// In the case the arg is null, the result will be equal to "null" and
308
330
// and otherwise we just take the 4th character of the string.
@@ -325,17 +347,24 @@ add_axioms_for_format_specifier(
325
347
return {res, constraints};
326
348
}
327
349
case format_specifiert::BOOLEAN:
328
- return_code = add_axioms_from_bool (res, get_arg (ID_boolean), array_pool);
350
+ return_code = add_axioms_from_bool (
351
+ res,
352
+ format_arg_from_string (string_arg, ID_boolean, array_pool),
353
+ array_pool);
329
354
return {res, std::move (return_code.second )};
330
355
case format_specifiert::STRING:
331
356
{
332
- const exprt arg_string = get_arg ( " string_expr " ) ;
357
+ const exprt arg_string = string_arg ;
333
358
const array_string_exprt string_expr = to_array_string_expr (arg_string);
334
359
return {std::move (string_expr), {}};
335
360
}
336
361
case format_specifiert::HASHCODE:
337
- return_code =
338
- add_axioms_for_string_of_int (res, get_arg (" hashcode" ), 0 , ns, array_pool);
362
+ return_code = add_axioms_for_string_of_int (
363
+ res,
364
+ format_arg_from_string (string_arg, " hashcode" , array_pool),
365
+ 0 ,
366
+ ns,
367
+ array_pool);
339
368
return {res, std::move (return_code.second )};
340
369
case format_specifiert::LINE_SEPARATOR:
341
370
// TODO: the constant should depend on the system: System.lineSeparator()
@@ -358,7 +387,7 @@ add_axioms_for_format_specifier(
358
387
auto format_specifier_result = add_axioms_for_format_specifier (
359
388
fresh_symbol,
360
389
fs_lower,
361
- get_arg ,
390
+ string_arg ,
362
391
index_type,
363
392
char_type,
364
393
array_pool,
@@ -463,13 +492,13 @@ std::pair<exprt, string_constraintst> add_axioms_for_format(
463
492
const typet &char_type = res.content ().type ().subtype ();
464
493
const typet &index_type = res.length_type ();
465
494
495
+ array_string_exprt string_arg;
496
+
466
497
for (const format_elementt &fe : format_strings)
467
498
{
468
499
if (fe.is_format_specifier ())
469
500
{
470
501
const format_specifiert &fs = fe.get_format_specifier ();
471
- std::function<exprt (const irep_idt &)> get_arg =
472
- [](const irep_idt &) -> exprt { UNREACHABLE; };
473
502
474
503
if (
475
504
fs.conversion != format_specifiert::PERCENT_SIGN &&
@@ -497,17 +526,13 @@ std::pair<exprt, string_constraintst> add_axioms_for_format(
497
526
INVARIANT (
498
527
is_refined_string_type (arg.type ()),
499
528
" arguments of format should be strings" );
500
- const array_string_exprt string_arg = get_string_expr (array_pool, arg);
501
- // / REMOVE get_arg below
502
- get_arg = [&](const irep_idt &id) {
503
- return format_arg_from_string (string_arg, id, array_pool);
504
- };
529
+ string_arg = get_string_expr (array_pool, arg);
505
530
}
506
531
507
532
auto result = add_axioms_for_format_specifier (
508
533
fresh_symbol,
509
534
fs,
510
- get_arg ,
535
+ string_arg ,
511
536
index_type,
512
537
char_type,
513
538
array_pool,
0 commit comments