17
17
#include < linking/static_lifetime_init.h>
18
18
19
19
#include " java_object_factory.h"
20
+ #include " java_string_literals.h"
20
21
#include " java_utils.h"
21
22
22
23
static void create_initialize (symbol_table_baset &symbol_table)
@@ -65,12 +66,44 @@ static bool should_init_symbol(const symbolt &sym)
65
66
return is_java_string_literal_id (sym.name );
66
67
}
67
68
69
+ irep_idt get_java_class_literal_initializer_signature ()
70
+ {
71
+ static irep_idt signature =
72
+ " java::java.lang.Class.cproverInitializeClassLiteral:"
73
+ " (Ljava/lang/String;ZZZZZZZ)V" ;
74
+ return signature;
75
+ }
76
+
77
+ // / If symbol is a class literal, and an appropriate initializer method exists,
78
+ // / return a pointer to its symbol. If not, return null.
79
+ // / \param symbol: possible class literal symbol
80
+ // / \param symbol_table: table to search
81
+ // / \return pointer to the initializer method symbol or null
82
+ static const symbolt *get_class_literal_initializer (
83
+ const symbolt &symbol,
84
+ const symbol_table_baset &symbol_table)
85
+ {
86
+ if (symbol.value .is_not_nil ())
87
+ return nullptr ;
88
+ if (symbol.type != symbol_typet (" java::java.lang.Class" ))
89
+ return nullptr ;
90
+ if (!has_suffix (id2string (symbol.name ), " @class_model" ))
91
+ return nullptr ;
92
+ return symbol_table.lookup (get_java_class_literal_initializer_signature ());
93
+ }
94
+
95
+ static constant_exprt constant_bool (bool val)
96
+ {
97
+ return from_integer (val ? 1 : 0 , java_boolean_type ());
98
+ }
99
+
68
100
static void java_static_lifetime_init (
69
101
symbol_table_baset &symbol_table,
70
102
const source_locationt &source_location,
71
103
bool assume_init_pointers_not_null,
72
104
const object_factory_parameterst &object_factory_parameters,
73
- const select_pointer_typet &pointer_type_selector)
105
+ const select_pointer_typet &pointer_type_selector,
106
+ bool string_refinement_enabled)
74
107
{
75
108
symbolt &initialize_symbol=*symbol_table.get_writeable (INITIALIZE_FUNCTION);
76
109
code_blockt &code_block=to_code_block (to_code (initialize_symbol.value ));
@@ -88,7 +121,53 @@ static void java_static_lifetime_init(
88
121
const symbolt &sym=*symbol_table.lookup (symname);
89
122
if (should_init_symbol (sym))
90
123
{
91
- if (sym.value .is_nil () && sym.type !=empty_typet ())
124
+ if (const symbolt *class_literal_init_method =
125
+ get_class_literal_initializer (sym, symbol_table))
126
+ {
127
+ const std::string &name_str = id2string (sym.name );
128
+ irep_idt class_name =
129
+ name_str.substr (0 , name_str.size () - strlen (" @class_model" ));
130
+ const symbolt &class_symbol = symbol_table.lookup_ref (class_name);
131
+
132
+ bool class_is_array = has_prefix (name_str, " java::array[" );
133
+
134
+ exprt name_literal (ID_java_string_literal);
135
+ name_literal.set (ID_value, to_class_type (class_symbol.type ).get_tag ());
136
+
137
+ symbol_exprt class_name_literal =
138
+ get_or_create_string_literal_symbol (
139
+ name_literal, symbol_table, string_refinement_enabled);
140
+
141
+ // Call the literal initializer method instead of a nondet initializer:
142
+
143
+ // For arguments we can't parse yet:
144
+ side_effect_expr_nondett nondet_bool (java_boolean_type ());
145
+
146
+ // Argument order is: name, isAnnotation, isArray, isInterface,
147
+ // isSynthetic, isLocalClass, isMemberClass, isEnum
148
+
149
+ code_function_callt initializer_call;
150
+ initializer_call.function () = class_literal_init_method->symbol_expr ();
151
+
152
+ code_function_callt::argumentst &args = initializer_call.arguments ();
153
+
154
+ args.push_back (address_of_exprt (sym.symbol_expr ())); /* this */
155
+ args.push_back (address_of_exprt (class_name_literal));
156
+ args.push_back (
157
+ constant_bool (class_symbol.type .get_bool (ID_is_annotation)));
158
+ args.push_back (constant_bool (class_is_array));
159
+ args.push_back (
160
+ constant_bool (class_symbol.type .get_bool (ID_interface)));
161
+ args.push_back (
162
+ constant_bool (class_symbol.type .get_bool (ID_synthetic)));
163
+ args.push_back (nondet_bool);
164
+ args.push_back (nondet_bool);
165
+ args.push_back (
166
+ constant_bool (class_symbol.type .get_bool (ID_enumeration)));
167
+
168
+ code_block.move_to_operands (initializer_call);
169
+ }
170
+ else if (sym.value .is_nil () && sym.type !=empty_typet ())
92
171
{
93
172
bool allow_null=!assume_init_pointers_not_null;
94
173
if (allow_null)
@@ -403,7 +482,8 @@ bool java_entry_point(
403
482
message_handlert &message_handler,
404
483
bool assume_init_pointers_not_null,
405
484
const object_factory_parameterst &object_factory_parameters,
406
- const select_pointer_typet &pointer_type_selector)
485
+ const select_pointer_typet &pointer_type_selector,
486
+ bool string_refinement_enabled)
407
487
{
408
488
// check if the entry point is already there
409
489
if (symbol_table.symbols .find (goto_functionst::entry_point ())!=
@@ -426,7 +506,8 @@ bool java_entry_point(
426
506
symbol.location ,
427
507
assume_init_pointers_not_null,
428
508
object_factory_parameters,
429
- pointer_type_selector);
509
+ pointer_type_selector,
510
+ string_refinement_enabled);
430
511
431
512
return generate_java_start_function (
432
513
symbol,
0 commit comments