Skip to content

Commit 1da5be1

Browse files
committed
Add tests for inherited static fields
These cover various permutations of static fields defined on parents, on interfaces, and those parents and/or interfaces being opaque (stubs). They check both that jbmc doesn't outright crash, and in some cases that jbmc correctly determines that two static fields must be the same one, and therefore cannot differ.
1 parent f15c312 commit 1da5be1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+787
-0
lines changed
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public class Test extends Parent {
2+
3+
public static void main(int nondet) {
4+
5+
x = nondet;
6+
assert x == Parent.x;
7+
8+
}
9+
10+
}
11+
12+
class Parent {
13+
14+
public static int x;
15+
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
Test.class
3+
4+
^VERIFICATION SUCCESSFUL$
5+
--
6+
--
7+
This checks that jbmc knows that test.x and parent.x refer to the same field.
8+
Both test and parent are concrete (available) classes.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
public class Parent {
3+
4+
// This is the version of Parent we will run jbmc against, which has
5+
// a static field 'x', but that field is private and cannot correspond
6+
// to the reference 'Test.x'.
7+
private static int x;
8+
9+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class Test extends Parent {
2+
3+
public static void main(int nondet) {
4+
5+
x = nondet;
6+
assert x == Parent.x;
7+
8+
}
9+
10+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
public class Parent {
3+
4+
// This is the version of Parent we compile Test.java against, which does
5+
// have a static field 'x'.
6+
public static int x;
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
Test.class
3+
4+
Stub static field x found for non-stub type java::Test\. In future this will be a fatal error\.
5+
assertion at file Test\.java line 6 .* FAILURE
6+
^VERIFICATION FAILED$
7+
--
8+
Stub static field x found for non-stub type java::Parent\. In future this will be a fatal error\.
9+
--
10+
This test is the same as inherited_static_field9, except that the version of Parent we run against
11+
has a private static field that Test's 'x' cannot be referring to.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import java.util.ArrayList;
2+
3+
interface InterfaceWithStatic {
4+
5+
// The ArrayList is only here to define a constant x that
6+
// is complicated enough for javac to generate a static init
7+
// rather than just propagate the constant to all users.
8+
static ArrayList<Integer> al = new ArrayList<Integer>();
9+
static int x = al.size();
10+
11+
}
12+
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public class Test extends Parent implements InterfaceWithStatic {
2+
3+
public static void main() {
4+
5+
int val1 = InterfaceWithStatic.x;
6+
int val2 = x;
7+
assert val1 == val2;
8+
9+
}
10+
11+
}
12+
13+
class Parent {
14+
15+
}
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
Test.class
3+
4+
^VERIFICATION SUCCESSFUL$
5+
--
6+
--
7+
This checks that jbmc knows that Test.x and InterfaceWithStatic.x are the same field.
8+
All types are concrete (not stubs).
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
public class Test extends OpaqueParent {
2+
3+
public static void main() {
4+
5+
assert x == OpaqueParent.x;
6+
7+
}
8+
9+
}
10+
11+
class OpaqueParent {
12+
13+
public static int x;
14+
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
Test.class
3+
4+
^VERIFICATION SUCCESSFUL$
5+
--
6+
--
7+
This is the same as test inherited_static_field1, except Test's parent is opaque.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
public class Test extends Parent {
2+
3+
public static void main(int nondet) {
4+
5+
x = nondet;
6+
assert x == Grandparent.x;
7+
8+
}
9+
10+
}
11+
12+
class Parent extends Grandparent {
13+
14+
public static int x;
15+
16+
}
17+
18+
class Grandparent {
19+
20+
public static int x;
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Test.class
3+
4+
assertion at file Test\.java line 6 .* FAILURE
5+
^VERIFICATION FAILED$
6+
--
7+
--
8+
This checks that jbmc knows that the hidden field Grandparent.x is not the same
9+
as Test.x, which resolves to Parent.x.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import java.util.ArrayList;
2+
3+
interface InterfaceWithStatic {
4+
5+
// The ArrayList is only here to define a constant x that
6+
// is complicated enough for javac to generate a static init
7+
// rather than just propagate the constant to all users.
8+
static ArrayList<Integer> al = new ArrayList<Integer>();
9+
static int x = al.size();
10+
11+
}
12+
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public class Test extends OpaqueParent implements InterfaceWithStatic {
2+
3+
public static void main() {
4+
5+
int val1 = x;
6+
int val2 = InterfaceWithStatic.x;
7+
assert val1 == val2;
8+
9+
}
10+
11+
}
12+
13+
class OpaqueParent {
14+
15+
}
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
Test.class
3+
4+
^VERIFICATION SUCCESSFUL$
5+
--
6+
--
7+
This is the same as inherited_static_field2, except that Test's parent is opaque. It must pass because
8+
the field 'x' should be found on InterfaceWithStatic, and so not created as a stub on OpaqueParent.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
public class Test extends OpaqueParent {
2+
3+
public static void main(int nondet) {
4+
5+
x = nondet;
6+
assert x == Grandparent.x;
7+
8+
}
9+
10+
}
11+
12+
class OpaqueParent extends Grandparent {
13+
14+
public static int x;
15+
16+
}
17+
18+
class Grandparent {
19+
20+
public static int x;
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
Test.class
3+
4+
assertion at file Test\.java line 6 .* FAILURE
5+
^VERIFICATION FAILED$
6+
--
7+
--
8+
This test is the same as inherited_static_field4, except that Test's parent is opaque.
9+
This checks that jbmc guesses that the hidden field Grandparent.x is not the same
10+
as Test.x, which may resolve to the (unseen) Parent.x.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import java.util.ArrayList;
2+
3+
interface OpaqueInterfaceWithStatic {
4+
5+
// The ArrayList is only here to define a constant x that
6+
// is complicated enough for javac to generate a static init
7+
// rather than just propagate the constant to all users.
8+
static ArrayList<Integer> al = new ArrayList<Integer>();
9+
static int x = al.size();
10+
11+
}
12+
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
public class Test implements OpaqueInterfaceWithStatic {
2+
3+
public static void main() {
4+
5+
int val1 = x;
6+
int val2 = OpaqueInterfaceWithStatic.x;
7+
assert val1 == val2;
8+
9+
}
10+
11+
}
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Test.class
3+
4+
^VERIFICATION SUCCESSFUL$
5+
--
6+
--
7+
This test must pass, as there is only one opaque parent (interface_with_static).
8+
In particular this one makes sure we don't identify Object as opaque and guess that
9+
java.lang.Object.x exists (since we know Object doesn't have static fields).
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
public class Test extends Parent {
2+
3+
public static void main(int nondet) {
4+
5+
x = nondet;
6+
assert x == Parent.x;
7+
assert x == OpaqueGrandparent.x;
8+
9+
}
10+
11+
}
12+
13+
class Parent extends OpaqueGrandparent {
14+
15+
public static int x;
16+
17+
}
18+
19+
class OpaqueGrandparent {
20+
21+
public static int x;
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
Test.class
3+
4+
assertion at file Test\.java line 6 .* SUCCESS
5+
assertion at file Test\.java line 7 .* FAILURE
6+
^VERIFICATION FAILED$
7+
--
8+
--
9+
This test is the same as inherited_static_field4, except that Test's grandparent is opaque.
10+
This checks that jbmc infers that the hidden field Grandparent.x is not the same
11+
as Test.x, which is known to resolve to Parent.x.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
public class Parent {
3+
4+
// This is the version of Parent we will run jbmc against, which does
5+
// not have a static field 'x'.
6+
7+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class Test extends Parent {
2+
3+
public static void main(int nondet) {
4+
5+
x = nondet;
6+
assert x == Parent.x;
7+
8+
}
9+
10+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
public class Parent {
3+
4+
// This is the version of Parent we compile Test.java against, which does
5+
// have a static field 'x'.
6+
public static int x;
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
Test.class
3+
4+
Stub static field x found for non-stub type java::Test\. In future this will be a fatal error\.
5+
Stub static field x found for non-stub type java::Parent\. In future this will be a fatal error\.
6+
assertion at file Test\.java line 6 .* FAILURE
7+
^VERIFICATION FAILED$
8+
--
9+
--
10+
This tests the corner case where static fields are found on non-stub types, here caused
11+
by compiling Test.class against a version of Parent.class (in directory compile_against)
12+
that has a static field but then analysing it with one that doesn't have that field.
13+
In future, as the warning messages we check for note, this will be a fatal error.

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SRC += unit_tests.cpp \
2525
miniBDD_new.cpp \
2626
java_bytecode/java_string_library_preprocess/convert_exprt_to_string_exprt.cpp \
2727
java_bytecode/java_utils_test.cpp \
28+
java_bytecode/inherited_static_fields/inherited_static_fields.cpp \
2829
pointer-analysis/custom_value_set_analysis.cpp \
2930
sharing_node.cpp \
3031
solvers/refinement/string_constraint_generator_valueof/calculate_max_string_length.cpp \
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
public class Test1 extends Parent1 {
3+
4+
public static int main() {
5+
return x;
6+
}
7+
8+
}
9+
10+
class Parent1 {
11+
public static int x;
12+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
import java.util.ArrayList;
3+
4+
public class Test2 implements StaticInterface2 {
5+
6+
public static int main() {
7+
return x;
8+
}
9+
10+
}
11+
12+
interface StaticInterface2 {
13+
// The ArrayList is only here to define a constant x that
14+
// is complicated enough for javac to generate a static init
15+
// rather than just propagate the constant to all users.
16+
static ArrayList<Integer> al = new ArrayList<Integer>();
17+
static int x = al.size();
18+
}
Binary file not shown.

0 commit comments

Comments
 (0)