@@ -105,6 +105,124 @@ static constant_exprt constant_bool(bool val)
105
105
return from_integer (val ? 1 : 0 , java_boolean_type ());
106
106
}
107
107
108
+ static std::unordered_set<irep_idt> init_symbol (
109
+ const symbolt &sym,
110
+ code_blockt &code_block,
111
+ symbol_table_baset &symbol_table,
112
+ const source_locationt &source_location,
113
+ bool assume_init_pointers_not_null,
114
+ const java_object_factory_parameterst &object_factory_parameters,
115
+ const select_pointer_typet &pointer_type_selector,
116
+ bool string_refinement_enabled,
117
+ message_handlert &message_handler)
118
+ {
119
+ std::unordered_set<irep_idt> additional_symbols;
120
+
121
+ if (
122
+ const symbolt *class_literal_init_method =
123
+ get_class_literal_initializer (sym, symbol_table))
124
+ {
125
+ const std::string &name_str = id2string (sym.name );
126
+ irep_idt class_name =
127
+ name_str.substr (0 , name_str.size () - strlen (JAVA_CLASS_MODEL_SUFFIX));
128
+ const symbolt &class_symbol = symbol_table.lookup_ref (class_name);
129
+
130
+ bool class_is_array = is_java_array_tag (sym.name );
131
+
132
+ journalling_symbol_tablet journalling_table =
133
+ journalling_symbol_tablet::wrap (symbol_table);
134
+
135
+ symbol_exprt class_name_literal = get_or_create_string_literal_symbol (
136
+ to_class_type (class_symbol.type ).get_tag (),
137
+ journalling_table,
138
+ string_refinement_enabled);
139
+
140
+ // If that created any new symbols make sure we initialise those too:
141
+ additional_symbols = journalling_table.get_inserted ();
142
+
143
+ // Call the literal initializer method instead of a nondet initializer:
144
+
145
+ // For arguments we can't parse yet:
146
+ side_effect_expr_nondett nondet_bool (java_boolean_type (), sym.location );
147
+
148
+ const auto &java_class_type = to_java_class_type (class_symbol.type );
149
+
150
+ // Argument order is: name, isAnnotation, isArray, isInterface,
151
+ // isSynthetic, isLocalClass, isMemberClass, isEnum
152
+
153
+ code_function_callt initializer_call (
154
+ class_literal_init_method->symbol_expr (),
155
+ {// this:
156
+ address_of_exprt (sym.symbol_expr ()),
157
+ // name:
158
+ address_of_exprt (class_name_literal),
159
+ // isAnnotation:
160
+ constant_bool (java_class_type.get_is_annotation ()),
161
+ // isArray:
162
+ constant_bool (class_is_array),
163
+ // isInterface:
164
+ constant_bool (java_class_type.get_interface ()),
165
+ // isSynthetic:
166
+ constant_bool (java_class_type.get_synthetic ()),
167
+ // isLocalClass:
168
+ nondet_bool,
169
+ // isMemberClass:
170
+ nondet_bool,
171
+ // isEnum:
172
+ constant_bool (java_class_type.get_is_enumeration ())});
173
+
174
+ // First initialize the object as prior to a constructor:
175
+ namespacet ns (symbol_table);
176
+
177
+ auto zero_object = zero_initializer (sym.type , source_locationt (), ns);
178
+ if (!zero_object.has_value ())
179
+ {
180
+ messaget message (message_handler);
181
+ message.error () << " failed to zero-initialize " << sym.name
182
+ << messaget::eom;
183
+ throw 0 ;
184
+ }
185
+ set_class_identifier (
186
+ to_struct_expr (*zero_object), ns, to_struct_tag_type (sym.type ));
187
+
188
+ code_block.add (std::move (code_assignt (sym.symbol_expr (), *zero_object)));
189
+
190
+ // Then call the init function:
191
+ code_block.add (std::move (initializer_call));
192
+ }
193
+ else if (sym.value .is_nil () && sym.type != java_void_type ())
194
+ {
195
+ const bool is_class_model = has_suffix (id2string (sym.name ), " @class_model" );
196
+ const bool not_allow_null = is_java_string_literal_id (sym.name ) ||
197
+ is_non_null_library_global (sym.name ) ||
198
+ assume_init_pointers_not_null;
199
+
200
+ java_object_factory_parameterst parameters = object_factory_parameters;
201
+ if (not_allow_null && !is_class_model)
202
+ parameters.min_null_tree_depth = 1 ;
203
+
204
+ gen_nondet_init (
205
+ sym.symbol_expr (),
206
+ code_block,
207
+ symbol_table,
208
+ source_location,
209
+ false ,
210
+ lifetimet::STATIC_GLOBAL,
211
+ parameters,
212
+ pointer_type_selector,
213
+ update_in_placet::NO_UPDATE_IN_PLACE,
214
+ message_handler);
215
+ }
216
+ else if (sym.value .is_not_nil ())
217
+ {
218
+ code_assignt assignment (sym.symbol_expr (), sym.value );
219
+ assignment.add_source_location () = source_location;
220
+ code_block.add (assignment);
221
+ }
222
+
223
+ return additional_symbols;
224
+ }
225
+
108
226
void java_static_lifetime_init (
109
227
symbol_table_baset &symbol_table,
110
228
const source_locationt &source_location,
@@ -152,114 +270,21 @@ void java_static_lifetime_init(
152
270
symbol_it != symbol_names.end ();
153
271
++symbol_it)
154
272
{
155
- const auto &symname = *symbol_it;
156
- const symbolt &sym = symbol_table.lookup_ref (symname);
273
+ const symbolt &sym = symbol_table.lookup_ref (*symbol_it);
157
274
if (should_init_symbol (sym))
158
275
{
159
- if (const symbolt *class_literal_init_method =
160
- get_class_literal_initializer (sym, symbol_table))
161
- {
162
- const std::string &name_str = id2string (sym.name );
163
- irep_idt class_name =
164
- name_str.substr (0 , name_str.size () - strlen (JAVA_CLASS_MODEL_SUFFIX));
165
- const symbolt &class_symbol = symbol_table.lookup_ref (class_name);
166
-
167
- bool class_is_array = is_java_array_tag (sym.name );
168
-
169
- journalling_symbol_tablet journalling_table =
170
- journalling_symbol_tablet::wrap (symbol_table);
171
-
172
- symbol_exprt class_name_literal = get_or_create_string_literal_symbol (
173
- to_class_type (class_symbol.type ).get_tag (),
174
- journalling_table,
175
- string_refinement_enabled);
176
-
177
- // If that created any new symbols make sure we initialise those too:
178
- const auto &new_symbols = journalling_table.get_inserted ();
179
- symbol_names.insert (
180
- symbol_names.end (), new_symbols.begin (), new_symbols.end ());
181
-
182
- // Call the literal initializer method instead of a nondet initializer:
183
-
184
- // For arguments we can't parse yet:
185
- side_effect_expr_nondett nondet_bool (java_boolean_type (), sym.location );
186
-
187
- const auto &java_class_type = to_java_class_type (class_symbol.type );
188
-
189
- // Argument order is: name, isAnnotation, isArray, isInterface,
190
- // isSynthetic, isLocalClass, isMemberClass, isEnum
191
-
192
- code_function_callt initializer_call (
193
- class_literal_init_method->symbol_expr (),
194
- {// this:
195
- address_of_exprt (sym.symbol_expr ()),
196
- // name:
197
- address_of_exprt (class_name_literal),
198
- // isAnnotation:
199
- constant_bool (java_class_type.get_is_annotation ()),
200
- // isArray:
201
- constant_bool (class_is_array),
202
- // isInterface:
203
- constant_bool (java_class_type.get_interface ()),
204
- // isSynthetic:
205
- constant_bool (java_class_type.get_synthetic ()),
206
- // isLocalClass:
207
- nondet_bool,
208
- // isMemberClass:
209
- nondet_bool,
210
- // isEnum:
211
- constant_bool (java_class_type.get_is_enumeration ())});
212
-
213
- // First initialize the object as prior to a constructor:
214
- namespacet ns (symbol_table);
215
-
216
- auto zero_object = zero_initializer (sym.type , source_locationt (), ns);
217
- if (!zero_object.has_value ())
218
- {
219
- messaget message (message_handler);
220
- message.error () << " failed to zero-initialize " << sym.name
221
- << messaget::eom;
222
- throw 0 ;
223
- }
224
- set_class_identifier (
225
- to_struct_expr (*zero_object), ns, to_struct_tag_type (sym.type ));
226
-
227
- code_block.add (
228
- std::move (code_assignt (sym.symbol_expr (), *zero_object)));
229
-
230
- // Then call the init function:
231
- code_block.add (std::move (initializer_call));
232
- }
233
- else if (sym.value .is_nil () && sym.type != java_void_type ())
234
- {
235
- const bool is_class_model =
236
- has_suffix (id2string (sym.name ), " @class_model" );
237
- const bool not_allow_null = is_java_string_literal_id (sym.name ) ||
238
- is_non_null_library_global (sym.name ) ||
239
- assume_init_pointers_not_null;
240
-
241
- java_object_factory_parameterst parameters = object_factory_parameters;
242
- if (not_allow_null && !is_class_model)
243
- parameters.min_null_tree_depth = 1 ;
244
-
245
- gen_nondet_init (
246
- sym.symbol_expr (),
247
- code_block,
248
- symbol_table,
249
- source_location,
250
- false ,
251
- lifetimet::STATIC_GLOBAL,
252
- parameters,
253
- pointer_type_selector,
254
- update_in_placet::NO_UPDATE_IN_PLACE,
255
- message_handler);
256
- }
257
- else if (sym.value .is_not_nil ())
258
- {
259
- code_assignt assignment (sym.symbol_expr (), sym.value );
260
- assignment.add_source_location ()=source_location;
261
- code_block.add (assignment);
262
- }
276
+ auto new_symbols = init_symbol (
277
+ sym,
278
+ code_block,
279
+ symbol_table,
280
+ source_location,
281
+ assume_init_pointers_not_null,
282
+ object_factory_parameters,
283
+ pointer_type_selector,
284
+ string_refinement_enabled,
285
+ message_handler);
286
+ symbol_names.insert (
287
+ symbol_names.end (), new_symbols.begin (), new_symbols.end ());
263
288
}
264
289
}
265
290
initialize_symbol.value = std::move (code_block);
0 commit comments