Skip to content

Commit efae909

Browse files
Merge pull request diffblue#1603 from romainbrenguier/feature/cproverValidate#TG1313
Add call to cproverValidate in nondet initialization TG-1313
2 parents aa88e27 + 4fd14b2 commit efae909

File tree

6 files changed

+70
-1
lines changed

6 files changed

+70
-1
lines changed
896 Bytes
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import org.cprover.CProver;
2+
3+
class Test {
4+
int size;
5+
int[] data1;
6+
int[] data2;
7+
8+
void cproverNondetInitialize() {
9+
// This specifies invariants about object of this class.
10+
// This avoids finding spurious bugs.
11+
CProver.assume(data1 != null && data2 != null && size == data1.length + data2.length);
12+
}
13+
14+
int check(int x) {
15+
int i;
16+
if(x >= size || x < 0)
17+
return -1;
18+
19+
assert(data1 != null || data2 == null);
20+
21+
if (x >= data1.length) {
22+
i = x - data1.length;
23+
assert(i < data2.length);
24+
return data2[i];
25+
} else {
26+
assert(x < data1.length);
27+
return data1[x];
28+
}
29+
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CORE
2+
Test.class
3+
--function Test.check
4+
^VERIFICATION SUCCESSFUL$
5+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CORE
2+
Test.class
3+
--function Test.check --lazy-methods
4+
^VERIFICATION SUCCESSFUL$
5+
--

src/java_bytecode/ci_lazy_methods_needed.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,14 @@ bool ci_lazy_methods_neededt::add_needed_class(
3434
{
3535
if(!needed_classes.insert(class_symbol_name).second)
3636
return false;
37-
const irep_idt clinit_name(id2string(class_symbol_name)+".<clinit>:()V");
37+
const std::string &class_name_string = id2string(class_symbol_name);
38+
const irep_idt clinit_name(class_name_string + ".<clinit>:()V");
3839
if(symbol_table.symbols.count(clinit_name))
3940
add_needed_method(clinit_name);
41+
42+
const irep_idt cprover_validate(
43+
class_name_string + ".cproverNondetInitialize:()V");
44+
if(symbol_table.symbols.count(cprover_validate))
45+
add_needed_method(cprover_validate);
4046
return true;
4147
}

src/java_bytecode/java_object_factory.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,8 @@ symbol_exprt java_object_factoryt::gen_nondet_subtype_pointer_init(
926926
/// Initializes an object tree rooted at `expr`, allocating child objects as
927927
/// necessary and nondet-initializes their members, or if MUST_UPDATE_IN_PLACE
928928
/// is set, re-initializes already-allocated objects.
929+
/// After initialization calls validation method
930+
/// `expr.cproverNondetInitialize()` if it was provided by the user.
929931
///
930932
/// \param assignments:
931933
/// The code block to append the new instructions to.
@@ -1028,6 +1030,26 @@ void java_object_factoryt::gen_nondet_struct_init(
10281030
substruct_in_place);
10291031
}
10301032
}
1033+
1034+
// If <class_identifier>.cproverValidate() can be found in the
1035+
// symbol table, we add a call:
1036+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1037+
// expr.cproverValidate();
1038+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1039+
1040+
const irep_idt validate_method_name =
1041+
"java::" + id2string(class_identifier) + ".cproverNondetInitialize:()V";
1042+
1043+
if(const auto func = symbol_table.lookup(validate_method_name))
1044+
{
1045+
const code_typet &type = to_code_type(func->type);
1046+
code_function_callt fun_call;
1047+
fun_call.function() = func->symbol_expr();
1048+
if(type.has_this())
1049+
fun_call.arguments().push_back(address_of_exprt(expr));
1050+
1051+
assignments.add(fun_call);
1052+
}
10311053
}
10321054

10331055
/// Initializes a primitive-typed or referece-typed object tree rooted at

0 commit comments

Comments
 (0)