@@ -27,11 +27,13 @@ class java_bytecode_convert_classt:public messaget
2727 symbol_tablet &_symbol_table,
2828 message_handlert &_message_handler,
2929 bool _disable_runtime_checks,
30- size_t _max_array_length):
30+ size_t _max_array_length,
31+ bool _string_refinement_enabled):
3132 messaget (_message_handler),
3233 symbol_table (_symbol_table),
3334 disable_runtime_checks (_disable_runtime_checks),
34- max_array_length (_max_array_length)
35+ max_array_length (_max_array_length),
36+ string_refinement_enabled (_string_refinement_enabled)
3537 {
3638 }
3739
@@ -41,6 +43,9 @@ class java_bytecode_convert_classt:public messaget
4143
4244 if (parse_tree.loading_successful )
4345 convert (parse_tree.parsed_class );
46+ else if (string_refinement_enabled &&
47+ parse_tree.parsed_class .name ==" java.lang.String" )
48+ add_string_type ();
4449 else
4550 generate_class_stub (parse_tree.parsed_class .name );
4651 }
@@ -52,13 +57,15 @@ class java_bytecode_convert_classt:public messaget
5257 symbol_tablet &symbol_table;
5358 const bool disable_runtime_checks;
5459 const size_t max_array_length;
60+ bool string_refinement_enabled;
5561
5662 // conversion
5763 void convert (const classt &c);
5864 void convert (symbolt &class_symbol, const fieldt &f);
5965
6066 void generate_class_stub (const irep_idt &class_name);
6167 void add_array_types ();
68+ void add_string_type ();
6269};
6370
6471/* ******************************************************************\
@@ -322,13 +329,15 @@ bool java_bytecode_convert_class(
322329 symbol_tablet &symbol_table,
323330 message_handlert &message_handler,
324331 bool disable_runtime_checks,
325- size_t max_array_length)
332+ size_t max_array_length,
333+ bool string_refinement_enabled)
326334{
327335 java_bytecode_convert_classt java_bytecode_convert_class (
328336 symbol_table,
329337 message_handler,
330338 disable_runtime_checks,
331- max_array_length);
339+ max_array_length,
340+ string_refinement_enabled);
332341
333342 try
334343 {
@@ -352,3 +361,63 @@ bool java_bytecode_convert_class(
352361
353362 return true ;
354363}
364+
365+ /* ******************************************************************\
366+
367+ Function: java_bytecode_convert_classt::add_string_type
368+
369+ Purpose: Implements the java.lang.String type in the case that
370+ we provide an internal implementation.
371+
372+ \*******************************************************************/
373+
374+ void java_bytecode_convert_classt::add_string_type ()
375+ {
376+ class_typet string_type;
377+ string_type.set_tag (" java.lang.String" );
378+ string_type.components ().resize (3 );
379+ string_type.components ()[0 ].set_name (" @java.lang.Object" );
380+ string_type.components ()[0 ].type ()=symbol_typet (" java::java.lang.Object" );
381+ string_type.components ()[1 ].set_name (" length" );
382+ string_type.components ()[1 ].set_pretty_name (" length" );
383+ string_type.components ()[1 ].type ()=java_int_type ();
384+ string_type.components ()[2 ].set_name (" data" );
385+ string_type.components ()[2 ].set_pretty_name (" data" );
386+ // Use a pointer-to-unbounded-array instead of a pointer-to-char.
387+ // Saves some casting in the string refinement algorithm but may
388+ // be unnecessary.
389+ string_type.components ()[2 ].type ()=pointer_typet (
390+ array_typet (java_char_type (), infinity_exprt (java_int_type ())));
391+ string_type.add_base (symbol_typet (" java::java.lang.Object" ));
392+
393+ symbolt string_symbol;
394+ string_symbol.name =" java::java.lang.String" ;
395+ string_symbol.base_name =" java.lang.String" ;
396+ string_symbol.type =string_type;
397+ string_symbol.is_type =true ;
398+
399+ symbol_table.add (string_symbol);
400+
401+ // Also add a stub of `String.equals` so that remove-virtual-functions
402+ // generates a check for Object.equals vs. String.equals.
403+ // No need to fill it in, as pass_preprocess will replace the calls again.
404+ symbolt string_equals_symbol;
405+ string_equals_symbol.name =
406+ " java::java.lang.String.equals:(Ljava/lang/Object;)Z" ;
407+ string_equals_symbol.base_name =" java.lang.String.equals" ;
408+ string_equals_symbol.pretty_name =" java.lang.String.equals" ;
409+ string_equals_symbol.mode =ID_java;
410+
411+ code_typet string_equals_type;
412+ string_equals_type.return_type ()=java_boolean_type ();
413+ code_typet::parametert thisparam;
414+ thisparam.set_this ();
415+ thisparam.type ()=pointer_typet (symbol_typet (string_symbol.name ));
416+ code_typet::parametert otherparam;
417+ otherparam.type ()=pointer_typet (symbol_typet (" java::java.lang.Object" ));
418+ string_equals_type.parameters ().push_back (thisparam);
419+ string_equals_type.parameters ().push_back (otherparam);
420+ string_equals_symbol.type =std::move (string_equals_type);
421+
422+ symbol_table.add (string_equals_symbol);
423+ }
0 commit comments