Skip to content

Commit aa5fcda

Browse files
authored
Merge pull request #4885 from danpoe/feature/constant-propagate-string-concatenation
[TG-8293] Constant propagation for empty strings and string concatenation [blocks: #4941]
2 parents d4e0bd0 + d9f75eb commit aa5fcda

File tree

48 files changed

+760
-60
lines changed

Some content is hidden

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

48 files changed

+760
-60
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Main {
2+
public void test() {
3+
String s1 = "abc";
4+
String s2 = "xyz";
5+
String s3 = s1 + s2;
6+
assert s3.equals("abcxyz");
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test --property "java::Main.test:()V.assertion.1" --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
public class Main {
2+
public void test1() {
3+
String s1 = "abc";
4+
String s2 = "xyz";
5+
String s3 = s1 + s2;
6+
assert s3.length() == 7;
7+
}
8+
9+
public void test2() {
10+
String s1 = "abc";
11+
String s2 = "xyz";
12+
String s3 = s1 + s2;
13+
assert s3.startsWith("abcdefg");
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
Main.class
3+
--function Main.test1
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
Main.class
3+
--function Main.test2
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class Main {
2+
public void test() {
3+
String s1 = "ディフ";
4+
String s2 = "ブルー";
5+
String s3 = s1 + s2;
6+
assert s3.length() == 6;
7+
assert s3.startsWith("ディフブルー");
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test --property "java::Main.test:()V.assertion.1" --property "java::Main.test:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class Main {
2+
public void test() {
3+
String s1 = "\t";
4+
String s2 = "\\";
5+
String s3 = s1 + s2;
6+
assert s3.length() == 2;
7+
assert s3.startsWith("\t\\");
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test --property "java::Main.test:()V.assertion.1" --property "java::Main.test:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class Main {
2+
public void test() {
3+
StringBuilder sb = new StringBuilder("abc");
4+
sb.append("xyz");
5+
String s = sb.toString();
6+
assert s.length() == 6;
7+
assert s.startsWith("abcxyz");
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test --property "java::Main.test:()V.assertion.1" --property "java::Main.test:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
public class Main {
2+
public void test1() {
3+
StringBuilder sb1 = new StringBuilder("abc");
4+
String s2 = "";
5+
sb1.append(s2);
6+
assert sb1.length() == 3;
7+
assert sb1.toString().startsWith("abc");
8+
}
9+
10+
public void test2() {
11+
StringBuilder sb1 = new StringBuilder();
12+
String s2 = "abc";
13+
sb1.append(s2);
14+
assert sb1.length() == 3;
15+
assert sb1.toString().startsWith("abc");
16+
}
17+
18+
public void test3() {
19+
StringBuilder sb1 = new StringBuilder();
20+
String s2 = "";
21+
sb1.append(s2);
22+
assert sb1.length() == 0;
23+
assert sb1.toString().startsWith("");
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test1 --property "java::Main.test1:()V.assertion.1" --property "java::Main.test1:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test2 --property "java::Main.test2:()V.assertion.1" --property "java::Main.test2:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test3 --property "java::Main.test3:()V.assertion.1" --property "java::Main.test3:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Main {
2+
public void test() {
3+
StringBuilder sb = new StringBuilder();
4+
String s = sb.toString();
5+
assert s.isEmpty();
6+
assert s.length() == 0;
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class Main {
2+
public void test() {
3+
String s1 = "abc";
4+
String s2 = "xyz";
5+
String s3 = s1 + s2;
6+
assert s3.length() == 6;
7+
assert s3.startsWith("abcxyz");
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test --property "java::Main.test:()V.assertion.1" --property "java::Main.test:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
public class Main {
2+
public void test1() {
3+
String s1 = "abc";
4+
String s2 = "";
5+
String s3 = s1 + s2;
6+
assert s3.length() == 3;
7+
assert s3.startsWith("abc");
8+
}
9+
10+
public void test2() {
11+
String s1 = "";
12+
String s2 = "abc";
13+
String s3 = s1 + s2;
14+
assert s3.length() == 3;
15+
assert s3.startsWith("abc");
16+
}
17+
18+
public void test3() {
19+
String s1 = "";
20+
String s2 = "";
21+
String s3 = s1 + s2;
22+
assert s3.length() == 0;
23+
assert s3.startsWith("");
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test1 --property "java::Main.test1:()V.assertion.1" --property "java::Main.test1:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test2 --property "java::Main.test2:()V.assertion.1" --property "java::Main.test2:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test3 --property "java::Main.test3:()V.assertion.1" --property "java::Main.test3:()V.assertion.2"
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class Main {
2+
public void test1(String s1) {
3+
String s2 = "abc";
4+
assert (s1 + s2).startsWith("abc");
5+
}
6+
7+
public void test2(String s) { assert ("" + s).startsWith("abc"); }
8+
9+
public void test3(String s) { assert (s + s).startsWith("abc"); }
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE symex-driven-lazy-loading-expected-failure
2+
Main.class
3+
--function Main.test1 --property "java::Main.test1:(Ljava/lang/String;)V.assertion.1"
4+
^Generated [0-9]+ VCC\(s\), 1 remaining after simplification$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
^VERIFICATION FAILED$
8+
--
9+
--
10+
This test checks that constant propagation does not happen, since a constant
11+
result cannot be determined from the arguments to `+`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE symex-driven-lazy-loading-expected-failure
2+
Main.class
3+
--function Main.test2 --property "java::Main.test2:(Ljava/lang/String;)V.assertion.1"
4+
^Generated [0-9]+ VCC\(s\), 1 remaining after simplification$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
^VERIFICATION FAILED$
8+
--
9+
--
10+
This test checks that constant propagation does not happen, since a constant
11+
result cannot be determined from the arguments to `+`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE symex-driven-lazy-loading-expected-failure
2+
Main.class
3+
--function Main.test3 --property "java::Main.test3:(Ljava/lang/String;)V.assertion.1"
4+
^Generated [0-9]+ VCC\(s\), 1 remaining after simplification$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
^VERIFICATION FAILED$
8+
--
9+
--
10+
This test checks that constant propagation does not happen, since a constant
11+
result cannot be determined from the arguments to `+`.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class Main {
2+
public void test() {
3+
String s = new String();
4+
assert s.isEmpty();
5+
assert s.startsWith("");
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Main.class
3+
--function Main.test
4+
^Generated [0-9]+ VCC\(s\), 0 remaining after simplification$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
^VERIFICATION SUCCESSFUL$
8+
--
9+
--

jbmc/src/java_bytecode/java_string_literals.cpp

+1-23
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,12 @@ Author: Chris Smowton, [email protected]
1515
#include <util/arith_tools.h>
1616
#include <util/expr_initializer.h>
1717
#include <util/namespace.h>
18+
#include <util/string_utils.h>
1819
#include <util/unicode.h>
1920

2021
#include <iomanip>
2122
#include <sstream>
2223

23-
/// Replace non-alphanumeric characters with `_xx` escapes, where xx are hex
24-
/// digits. Underscores are replaced by `__`.
25-
/// \param to_escape: string to escape
26-
/// \return string with non-alphanumeric characters escaped
27-
static std::string escape_non_alnum(const std::string &to_escape)
28-
{
29-
std::ostringstream escaped;
30-
for(auto &ch : to_escape)
31-
{
32-
if(ch=='_')
33-
escaped << "__";
34-
else if(isalnum(ch))
35-
escaped << ch;
36-
else
37-
escaped << '_'
38-
<< std::hex
39-
<< std::setfill('0')
40-
<< std::setw(2)
41-
<< (unsigned int)ch;
42-
}
43-
return escaped.str();
44-
}
45-
4624
/// Convert UCS-2 or UTF-16 to an array expression.
4725
/// \par parameters: `in`: wide string to convert
4826
/// \return Returns a Java char array containing the same wchars.

0 commit comments

Comments
 (0)