@@ -180,7 +180,9 @@ gen_clinit_eqexpr(const exprt &expr, const clinit_statest state)
180
180
181
181
// / Generates codet that iterates through the base types of the class specified
182
182
// / by class_name, C, and recursively adds calls to their clinit wrapper.
183
- // / Finally a call to the clinint wrapper of C is made.
183
+ // / Finally a call to the clinit of C is made. If nondet-static option was
184
+ // / given then all static variables that are not constants (i.e. final) are
185
+ // / then re-assigned to a nondet value.
184
186
// / \param symbol_table: symbol table
185
187
// / \param class_name: name of the class to generate clinit wrapper calls for
186
188
// / \param [out] init_body: appended with calls to clinit wrapper
@@ -191,7 +193,7 @@ gen_clinit_eqexpr(const exprt &expr, const clinit_statest state)
191
193
// / \param pointer_type_selector: used to choose concrete types for abstract-
192
194
// / typed globals and fields (only needed if nondet-static is true)
193
195
static void clinit_wrapper_do_recursive_calls (
194
- const symbol_tablet &symbol_table,
196
+ symbol_table_baset &symbol_table,
195
197
const irep_idt &class_name,
196
198
code_blockt &init_body,
197
199
const bool nondet_static,
@@ -218,6 +220,52 @@ static void clinit_wrapper_do_recursive_calls(
218
220
code_function_callt call_real_init;
219
221
call_real_init.function () = find_sym_it->second .symbol_expr ();
220
222
init_body.move_to_operands (call_real_init);
223
+
224
+ // Add a standard nondet initialization for each non-final static field
225
+ // of this class. Note this is the same invocation used in
226
+ // get_stub_initializer_body and java_static_lifetime_init.
227
+ if (nondet_static)
228
+ {
229
+ object_factory_parameterst parameters = object_factory_parameters;
230
+ parameters.function_id = clinit_wrapper_name (class_name);
231
+
232
+ std::vector<irep_idt> nondet_ids;
233
+ std::for_each (
234
+ symbol_table.symbols .begin (),
235
+ symbol_table.symbols .end (),
236
+ [&](const std::pair<irep_idt, symbolt> &symbol) {
237
+ if (
238
+ symbol.second .type .get (ID_C_class) == class_name &&
239
+ symbol.second .is_static_lifetime &&
240
+ !symbol.second .type .get_bool (ID_C_constant))
241
+ {
242
+ nondet_ids.push_back (symbol.first );
243
+ }
244
+ });
245
+
246
+ for (const auto &id : nondet_ids)
247
+ {
248
+ const symbol_exprt new_global_symbol =
249
+ symbol_table.lookup_ref (id).symbol_expr ();
250
+
251
+ parameters.max_nonnull_tree_depth =
252
+ is_non_null_library_global (id)
253
+ ? std::max (
254
+ size_t (1 ), object_factory_parameters.max_nonnull_tree_depth )
255
+ : object_factory_parameters.max_nonnull_tree_depth ;
256
+
257
+ gen_nondet_init (
258
+ new_global_symbol,
259
+ init_body,
260
+ symbol_table,
261
+ source_locationt (),
262
+ false ,
263
+ allocation_typet::DYNAMIC,
264
+ parameters,
265
+ pointer_type_selector,
266
+ update_in_placet::NO_UPDATE_IN_PLACE);
267
+ }
268
+ }
221
269
}
222
270
}
223
271
@@ -374,7 +422,8 @@ static void create_clinit_wrapper_symbols(
374
422
// / // ...
375
423
// / java::In::clinit_wrapper();
376
424
// /
377
- // / java::C::<clinit>();
425
+ // / java::C::<clinit>(); // or nondet-initialization of all static
426
+ // / // variables of C if nondet-static is true
378
427
// /
379
428
// / // Setting this variable to INIT_COMPLETE will let other threads "cross"
380
429
// / // beyond the assume() statement above in this function.
@@ -550,7 +599,8 @@ codet get_thread_safe_clinit_wrapper_body(
550
599
// // ...
551
600
// java::In::clinit_wrapper();
552
601
//
553
- // java::C::<clinit>();
602
+ // java::C::<clinit>(); // or nondet-initialization of all static
603
+ // // variables of C if nondet-static is true
554
604
//
555
605
{
556
606
code_blockt init_body;
@@ -616,7 +666,8 @@ codet get_clinit_wrapper_body(
616
666
// // ...
617
667
// java::In::clinit_wrapper();
618
668
//
619
- // java::C::<clinit>();
669
+ // java::C::<clinit>(); // or nondet-initialization of all static
670
+ // // variables of C if nondet-static is true
620
671
// }
621
672
// }
622
673
const symbolt &wrapper_method_symbol = symbol_table.lookup_ref (function_id);
0 commit comments