Skip to content

[TG-7648] Constant propagation of substring operations #4941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
public class Main {
public void test() {
StringBuilder sb = new StringBuilder("abc");

String s1 = sb.substring(0);
assert s1.length() == 3;
assert s1.startsWith("abc");

String s2 = sb.substring(1);
assert s2.length() == 2;
assert s2.startsWith("bc");

String s3 = sb.substring(0, 3);
assert s3.length() == 3;
assert s3.startsWith("abc");

String s4 = sb.substring(0, 0);
assert s4.length() == 0;
assert s4.startsWith("");

String s5 = sb.substring(0, 1);
assert s5.length() == 1;
assert s5.startsWith("a");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally check that out-of-range begin- or end-indices still throw as expected?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smowton Exceptions are a thing of the model library. There are already a couple of tests there:
https://github.com/diffblue/models-library/blob/develop/modelTests/maven/java/lang/String/src/main/java/L1Substring_int.java
https://github.com/diffblue/models-library/blob/develop/modelTests/maven/java/lang/String/src/main/java/L1Substring_int_int.java
which seem sufficient to me.

Of course these would only fail when the test-gen bump is updated, but I don't see how they coiuld.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @smowton is referring to the case where all the arguments to substring() are constant, but the indices are out of bounds. In this case the constant propagator should not simplify anything and the statement should just be symex'd normally. Whether that then later leads to an exception is a thing of the models library. I'll add a test to check that no simplification occurs for out of bounds indices.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE
Main.class
--function Main.test
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
public class Main {
public void test1(StringBuilder sb) {
String s = sb.substring(0);
assert s.startsWith("xyz");
}

public void test2(int i) {
StringBuilder sb = new StringBuilder("abc");

String s = sb.substring(i);
assert s.startsWith("xyz");
}

public void test3(StringBuilder sb, int i) {
String s = sb.substring(i);
assert s.startsWith("xyz");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE symex-driven-lazy-loading-expected-failure
Main.class
--function Main.test1 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --property "java::Main.test1:(Ljava/lang/StringBuilder;)V.assertion.1"
^Generated 1 VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
^VERIFICATION FAILED$
--
--
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE symex-driven-lazy-loading-expected-failure
Main.class
--function Main.test2 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --property "java::Main.test2:(I)V.assertion.1"
^Generated 1 VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
^VERIFICATION FAILED$
--
--
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE symex-driven-lazy-loading-expected-failure
Main.class
--function Main.test3 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --property "java::Main.test3:(Ljava/lang/StringBuilder;I)V.assertion.1"
^Generated 1 VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
^VERIFICATION FAILED$
--
--
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
public class Main {
public void test1() {
StringBuilder sb = new StringBuilder("abc");
sb.substring(-1);
}

public void test2() {
StringBuilder sb = new StringBuilder("abc");
sb.substring(4);
}

public void test3() {
StringBuilder sb = new StringBuilder("abc");
sb.substring(-1, 4);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FUTURE
Main.class
--function Main.test1 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [1-9][0-9]* VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
no uncaught exception: FAILURE
^VERIFICATION FAILED$
--
--
This test will pass once a model for StringBuilder.substring() exists that
throws an exception when the index is greater or equal to the length of the
string.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FUTURE
Main.class
--function Main.test2 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [1-9][0-9]* VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
no uncaught exception: FAILURE
^VERIFICATION FAILED$
--
--
This test will pass once a model for StringBuilder.substring() exists that
throws an exception when the index is greater or equal to the length of the
string.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FUTURE
Main.class
--function Main.test3 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [1-9][0-9]* VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
no uncaught exception: FAILURE
^VERIFICATION FAILED$
--
--
This test will pass once a model for StringBuilder.substring() exists that
throws an exception when the index is greater or equal to the length of the
string.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
public class Main {
public void test() {
String s = "abc";

String s1 = s.substring(0);
assert s1.equals("abc");

String s2 = s.substring(1);
assert s2.equals("bc");

String s3 = s.substring(0, 3);
assert s3.equals("abc");

String s4 = s.substring(0, 0);
assert s4.equals("");

String s5 = s.substring(0, 1);
assert s5.equals("a");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE
Main.class
--function Main.test --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
--
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
public class Main {
public void test1(String s1) {
String s2 = s1.substring(0);
assert s2.startsWith("xyz");
}

public void test2(int i) {
String s1 = "abc";

String s2 = s1.substring(i);
assert s2.startsWith("xyz");
}

public void test3(String s1, int i) {
String s2 = s1.substring(i);
assert s2.startsWith("xyz");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE symex-driven-lazy-loading-expected-failure
Main.class
--function Main.test1 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --property "java::Main.test1:(Ljava/lang/String;)V.assertion.1"
^Generated 1 VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
^VERIFICATION FAILED$
--
--
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE symex-driven-lazy-loading-expected-failure
Main.class
--function Main.test2 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --property "java::Main.test2:(I)V.assertion.1"
^Generated 1 VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
^VERIFICATION FAILED$
--
--
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE symex-driven-lazy-loading-expected-failure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea why the xfail?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using symex driven lazy loading it seems that jbmc does not fully honor the --property option as several additional VCCs are generated (e.g. null pointer checks). Those regression tests though check that a specific VCC is not simplified. This is currently done by selecting that VCC via --property and then checking that jbmc prints Generated 1 VCC(s), 1 remaining after simplification. If there would be more VCCs we could not check that this one VCC is the one that is not simplified.

Main.class
--function Main.test3 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --property "java::Main.test3:(Ljava/lang/String;I)V.assertion.1"
^Generated 1 VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
^VERIFICATION FAILED$
--
--
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
public class Main {
public void test1() {
String s1 = "abc";
s1.substring(-1);
}

public void test2() {
String s1 = "abc";
s1.substring(4);
}

public void test3() {
String s1 = "abc";
s1.substring(-1, 4);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
Main.class
--function Main.test1 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [1-9][0-9]* VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
no uncaught exception: FAILURE
^VERIFICATION FAILED$
--
--
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
Main.class
--function Main.test2 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [1-9][0-9]* VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
no uncaught exception: FAILURE
^VERIFICATION FAILED$
--
--
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
Main.class
--function Main.test3 --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
^Generated [1-9][0-9]* VCC\(s\), 1 remaining after simplification$
^EXIT=10$
^SIGNAL=0$
no uncaught exception: FAILURE
^VERIFICATION FAILED$
--
--
Loading