-
Notifications
You must be signed in to change notification settings - Fork 274
[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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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"); | ||
} | ||
} |
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$ | ||
-- | ||
-- |
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$ | ||
-- | ||
-- |
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. |
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$ | ||
-- | ||
-- |
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any idea why the xfail? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
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$ | ||
-- | ||
-- |
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$ | ||
-- | ||
-- |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.