Skip to content

Commit 0db1830

Browse files
authored
Merge pull request #4287 from smowton/smowton/fix/missing-enum-non-fatal
Make failed nondet Enum assignment non-fatal
2 parents 74caeca + 40d72fb commit 0db1830

11 files changed

+112
-56
lines changed

Diff for: jbmc/src/java_bytecode/convert_java_nondet.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ static goto_programt get_gen_nondet_init_instructions(
5757
skip_classid,
5858
lifetimet::DYNAMIC,
5959
object_factory_parameters,
60-
update_in_placet::NO_UPDATE_IN_PLACE);
60+
update_in_placet::NO_UPDATE_IN_PLACE,
61+
message_handler);
6162

6263
goto_programt instructions;
6364
goto_convert(

Diff for: jbmc/src/java_bytecode/java_bytecode_language.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,8 @@ bool java_bytecode_languaget::generate_support_functions(
869869
symbol_table,
870870
assume_inputs_non_null,
871871
object_factory_parameters,
872-
get_pointer_type_selector());
872+
get_pointer_type_selector(),
873+
get_message_handler());
873874
});
874875
}
875876

@@ -1068,22 +1069,25 @@ bool java_bytecode_languaget::convert_single_method(
10681069
symbol_table,
10691070
nondet_static,
10701071
object_factory_parameters,
1071-
get_pointer_type_selector());
1072+
get_pointer_type_selector(),
1073+
get_message_handler());
10721074
else
10731075
writable_symbol.value = get_clinit_wrapper_body(
10741076
function_id,
10751077
symbol_table,
10761078
nondet_static,
10771079
object_factory_parameters,
1078-
get_pointer_type_selector());
1080+
get_pointer_type_selector(),
1081+
get_message_handler());
10791082
break;
10801083
case synthetic_method_typet::STUB_CLASS_STATIC_INITIALIZER:
10811084
writable_symbol.value =
10821085
stub_global_initializer_factory.get_stub_initializer_body(
10831086
function_id,
10841087
symbol_table,
10851088
object_factory_parameters,
1086-
get_pointer_type_selector());
1089+
get_pointer_type_selector(),
1090+
get_message_handler());
10871091
break;
10881092
}
10891093
// Notify lazy methods of static calls made from the newly generated

Diff for: jbmc/src/java_bytecode/java_entry_point.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ static void java_static_lifetime_init(
258258
lifetimet::STATIC_GLOBAL,
259259
parameters,
260260
pointer_type_selector,
261-
update_in_placet::NO_UPDATE_IN_PLACE);
261+
update_in_placet::NO_UPDATE_IN_PLACE,
262+
message_handler);
262263
}
263264
else if(sym.value.is_not_nil())
264265
{
@@ -296,7 +297,8 @@ std::pair<code_blockt, std::vector<exprt>> java_build_arguments(
296297
symbol_table_baset &symbol_table,
297298
bool assume_init_pointers_not_null,
298299
java_object_factory_parameterst object_factory_parameters,
299-
const select_pointer_typet &pointer_type_selector)
300+
const select_pointer_typet &pointer_type_selector,
301+
message_handlert &message_handler)
300302
{
301303
const java_method_typet::parameterst &parameters =
302304
to_java_method_type(function.type).parameters();
@@ -354,7 +356,8 @@ std::pair<code_blockt, std::vector<exprt>> java_build_arguments(
354356
factory_parameters,
355357
lifetimet::AUTOMATIC_LOCAL,
356358
function.location,
357-
pointer_type_selector);
359+
pointer_type_selector,
360+
message_handler);
358361
}
359362
else
360363
{
@@ -400,7 +403,8 @@ std::pair<code_blockt, std::vector<exprt>> java_build_arguments(
400403
factory_parameters,
401404
lifetimet::DYNAMIC,
402405
function.location,
403-
pointer_type_selector);
406+
pointer_type_selector,
407+
message_handler);
404408
init_code_for_type.add(
405409
code_assignt(
406410
result_symbol.symbol_expr(),

Diff for: jbmc/src/java_bytecode/java_entry_point.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ bool generate_java_start_function(
169169
/// \param pointer_type_selector: Means of selecting the type of value
170170
/// constructed for reference types which are initialised by the code
171171
/// returned.
172+
/// \param message_handler: log
172173
/// \returns A pairing of the code to initialise the arguments and a std::vector
173174
/// of the expressions for these arguments. The vector contains one element
174175
/// per parameter of \p function. The vector of expressions can be used as
@@ -182,6 +183,7 @@ std::pair<code_blockt, std::vector<exprt>> java_build_arguments(
182183
symbol_table_baset &symbol_table,
183184
bool assume_init_pointers_not_null,
184185
java_object_factory_parameterst object_factory_parameters,
185-
const select_pointer_typet &pointer_type_selector);
186+
const select_pointer_typet &pointer_type_selector,
187+
message_handlert &message_handler);
186188

187189
#endif // CPROVER_JAVA_BYTECODE_JAVA_ENTRY_POINT_H

Diff for: jbmc/src/java_bytecode/java_object_factory.cpp

+45-26
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class java_object_factoryt
5959

6060
allocate_objectst allocate_objects;
6161

62+
/// Log for reporting warnings and errors in object creation
63+
messaget log;
64+
6265
code_assignt get_null_assignment(
6366
const exprt &expr,
6467
const pointer_typet &ptr_type);
@@ -84,7 +87,8 @@ class java_object_factoryt
8487
const source_locationt &loc,
8588
const java_object_factory_parameterst _object_factory_parameters,
8689
symbol_table_baset &_symbol_table,
87-
const select_pointer_typet &pointer_type_selector)
90+
const select_pointer_typet &pointer_type_selector,
91+
message_handlert &log)
8892
: loc(loc),
8993
object_factory_parameters(_object_factory_parameters),
9094
symbol_table(_symbol_table),
@@ -94,7 +98,8 @@ class java_object_factoryt
9498
ID_java,
9599
loc,
96100
object_factory_parameters.function_id,
97-
symbol_table)
101+
symbol_table),
102+
log(log)
98103
{}
99104

100105
void gen_nondet_array_init(
@@ -104,7 +109,7 @@ class java_object_factoryt
104109
update_in_placet,
105110
const source_locationt &location);
106111

107-
void gen_nondet_enum_init(
112+
bool gen_nondet_enum_init(
108113
code_blockt &assignments,
109114
const exprt &expr,
110115
const java_class_typet &java_class_type,
@@ -263,8 +268,8 @@ void java_object_factoryt::gen_pointer_target_init(
263268
}
264269
if(target_class_type.get_base("java::java.lang.Enum"))
265270
{
266-
gen_nondet_enum_init(assignments, expr, target_class_type, location);
267-
return;
271+
if(gen_nondet_enum_init(assignments, expr, target_class_type, location))
272+
return;
268273
}
269274
}
270275

@@ -1435,20 +1440,31 @@ void java_object_factoryt::gen_nondet_array_init(
14351440
/// int i = nondet(int);
14361441
/// assume(0 < = i < $VALUES.length);
14371442
/// expr = $VALUES[i];
1438-
/// where $VALUES is a variable generated by the Java compiler that stores
1439-
/// the array that is returned by Enum.values().
1440-
void java_object_factoryt::gen_nondet_enum_init(
1443+
/// where $VALUES is a variable generated by the Java compiler and which gives
1444+
/// the possible values of a particular enum subtype (this is the same array
1445+
/// that is returned by Enum.values()).
1446+
/// This may fail if the $VALUES static field is not present. Ensuring that
1447+
/// field is in the symbol table when this method may be applicable is the
1448+
/// driver program's responsibility: for example, \ref ci_lazy_methods.cpp makes
1449+
/// some effort to retain this field when a stub method might refer to it.
1450+
/// \return true on success
1451+
bool java_object_factoryt::gen_nondet_enum_init(
14411452
code_blockt &assignments,
14421453
const exprt &expr,
14431454
const java_class_typet &java_class_type,
14441455
const source_locationt &location)
14451456
{
14461457
const irep_idt &class_name = java_class_type.get_name();
14471458
const irep_idt values_name = id2string(class_name) + ".$VALUES";
1448-
INVARIANT(
1449-
ns.get_symbol_table().has_symbol(values_name),
1450-
"The $VALUES array (populated by clinit_wrapper) should be in the "
1451-
"symbol table");
1459+
if(!ns.get_symbol_table().has_symbol(values_name))
1460+
{
1461+
log.warning() << values_name
1462+
<< " is missing, so the corresponding Enum "
1463+
"type will nondet initialised"
1464+
<< messaget::eom;
1465+
return false;
1466+
}
1467+
14521468
const symbolt &values = ns.lookup(values_name);
14531469

14541470
// Access members (length and data) of $VALUES array
@@ -1473,6 +1489,8 @@ void java_object_factoryt::gen_nondet_enum_init(
14731489
const dereference_exprt arraycellref(plus);
14741490
code_assignt enum_assign(expr, typecast_exprt(arraycellref, expr.type()));
14751491
assignments.add(enum_assign);
1492+
1493+
return true;
14761494
}
14771495

14781496
static void assert_type_consistency(const code_blockt &assignments)
@@ -1510,7 +1528,8 @@ exprt object_factory(
15101528
java_object_factory_parameterst parameters,
15111529
lifetimet lifetime,
15121530
const source_locationt &loc,
1513-
const select_pointer_typet &pointer_type_selector)
1531+
const select_pointer_typet &pointer_type_selector,
1532+
message_handlert &log)
15141533
{
15151534
irep_idt identifier=id2string(goto_functionst::entry_point())+
15161535
"::"+id2string(base_name);
@@ -1531,10 +1550,7 @@ exprt object_factory(
15311550
CHECK_RETURN(!moving_symbol_failed);
15321551

15331552
java_object_factoryt state(
1534-
loc,
1535-
parameters,
1536-
symbol_table,
1537-
pointer_type_selector);
1553+
loc, parameters, symbol_table, pointer_type_selector, log);
15381554
code_blockt assignments;
15391555
state.gen_nondet_init(
15401556
assignments,
@@ -1587,6 +1603,7 @@ exprt object_factory(
15871603
/// MAY_UPDATE_IN_PLACE: generate a runtime nondet branch between the NO_
15881604
/// and MUST_ cases.
15891605
/// MUST_UPDATE_IN_PLACE: reinitialize an existing object
1606+
/// \param log: used to report object construction warnings and failures
15901607
/// \return `init_code` gets an instruction sequence to initialize or
15911608
/// reinitialize `expr` and child objects it refers to. `symbol_table` is
15921609
/// modified with any new symbols created. This includes any necessary
@@ -1600,13 +1617,11 @@ void gen_nondet_init(
16001617
lifetimet lifetime,
16011618
const java_object_factory_parameterst &object_factory_parameters,
16021619
const select_pointer_typet &pointer_type_selector,
1603-
update_in_placet update_in_place)
1620+
update_in_placet update_in_place,
1621+
message_handlert &log)
16041622
{
16051623
java_object_factoryt state(
1606-
loc,
1607-
object_factory_parameters,
1608-
symbol_table,
1609-
pointer_type_selector);
1624+
loc, object_factory_parameters, symbol_table, pointer_type_selector, log);
16101625
code_blockt assignments;
16111626
state.gen_nondet_init(
16121627
assignments,
@@ -1634,7 +1649,8 @@ exprt object_factory(
16341649
symbol_tablet &symbol_table,
16351650
const java_object_factory_parameterst &object_factory_parameters,
16361651
lifetimet lifetime,
1637-
const source_locationt &location)
1652+
const source_locationt &location,
1653+
message_handlert &log)
16381654
{
16391655
select_pointer_typet pointer_type_selector;
16401656
return object_factory(
@@ -1645,7 +1661,8 @@ exprt object_factory(
16451661
object_factory_parameters,
16461662
lifetime,
16471663
location,
1648-
pointer_type_selector);
1664+
pointer_type_selector,
1665+
log);
16491666
}
16501667

16511668
/// Call gen_nondet_init() above with a default (identity) pointer_type_selector
@@ -1657,7 +1674,8 @@ void gen_nondet_init(
16571674
bool skip_classid,
16581675
lifetimet lifetime,
16591676
const java_object_factory_parameterst &object_factory_parameters,
1660-
update_in_placet update_in_place)
1677+
update_in_placet update_in_place,
1678+
message_handlert &log)
16611679
{
16621680
select_pointer_typet pointer_type_selector;
16631681
gen_nondet_init(
@@ -1669,7 +1687,8 @@ void gen_nondet_init(
16691687
lifetime,
16701688
object_factory_parameters,
16711689
pointer_type_selector,
1672-
update_in_place);
1690+
update_in_place,
1691+
log);
16731692
}
16741693

16751694
/// Adds a call for the given method to the end of `assignments` if the method

Diff for: jbmc/src/java_bytecode/java_object_factory.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ exprt object_factory(
8787
java_object_factory_parameterst parameters,
8888
lifetimet lifetime,
8989
const source_locationt &location,
90-
const select_pointer_typet &pointer_type_selector);
90+
const select_pointer_typet &pointer_type_selector,
91+
message_handlert &log);
9192

9293
exprt object_factory(
9394
const typet &type,
@@ -96,7 +97,8 @@ exprt object_factory(
9697
symbol_tablet &symbol_table,
9798
const java_object_factory_parameterst &object_factory_parameters,
9899
lifetimet lifetime,
99-
const source_locationt &location);
100+
const source_locationt &location,
101+
message_handlert &log);
100102

101103
enum class update_in_placet
102104
{
@@ -114,7 +116,8 @@ void gen_nondet_init(
114116
lifetimet lifetime,
115117
const java_object_factory_parameterst &object_factory_parameters,
116118
const select_pointer_typet &pointer_type_selector,
117-
update_in_placet update_in_place);
119+
update_in_placet update_in_place,
120+
message_handlert &log);
118121

119122
void gen_nondet_init(
120123
const exprt &expr,
@@ -124,6 +127,7 @@ void gen_nondet_init(
124127
bool skip_classid,
125128
lifetimet lifetime,
126129
const java_object_factory_parameterst &object_factory_parameters,
127-
update_in_placet update_in_place);
130+
update_in_placet update_in_place,
131+
message_handlert &log);
128132

129133
#endif // CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H

0 commit comments

Comments
 (0)