Skip to content

Commit 278e4e6

Browse files
authored
Merge pull request diffblue#1826 from smowton/smowton/fix/java-inherited-static-fields
Add support for inheritence of Java static fields. Fixes TG-2457
2 parents a2ebb33 + 1da5be1 commit 278e4e6

File tree

96 files changed

+1321
-275
lines changed

Some content is hidden

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

96 files changed

+1321
-275
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.

src/goto-programs/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ SRC = basic_blocks.cpp \
5252
remove_vector.cpp \
5353
remove_virtual_functions.cpp \
5454
replace_java_nondet.cpp \
55-
resolve_concrete_function_call.cpp \
55+
resolve_inherited_component.cpp \
5656
safety_checker.cpp \
5757
set_properties.cpp \
5858
show_goto_functions.cpp \

0 commit comments

Comments
 (0)