Skip to content

Commit de7b8d2

Browse files
committed
Preserve existing details of string types
Previously the lambda handles, methods and similar were removed when all we need for the string solver is to ensure the type has a <length, data> member pair in the manner of an array type.
1 parent a1f60ea commit de7b8d2

File tree

9 files changed

+74
-19
lines changed

9 files changed

+74
-19
lines changed
626 Bytes
Binary file not shown.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class Test {
2+
3+
public static void testme() {
4+
assert String.usesLambdas(1) == 2;
5+
assert false; // Check we got here
6+
}
7+
8+
}
Binary file not shown.
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package java.lang;
2+
3+
public class String {
4+
5+
interface FunctionalIf {
6+
public int f(int x);
7+
}
8+
9+
public static int usesLambdas(int x) {
10+
FunctionalIf lambda = (n -> n + 1);
11+
return lambda.f(x);
12+
}
13+
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
Test
3+
--function Test.testme --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
4+
line 4 assertion at file Test\.java line 4 function java::Test\.testme:\(\)V bytecode-index 9: SUCCESS
5+
line 5 assertion at file Test\.java line 5 function java::Test\.testme:\(\)V bytecode-index 15: FAILURE
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
--
10+
This checks that a lambda functions work when defined on a string type (String, StringBuilder, StringBuffer,
11+
CharSequence, i.e. the types that the string solver may define or redefine)
12+
We use a dummy String type because the typical example in the wild, CharSequence.chars(), requires much
13+
more of the JDK than the tiny fragment present in jbmc's models library at present.

jbmc/src/java_bytecode/java_string_library_preprocess.cpp

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,43 @@ java_string_library_preprocesst::get_string_type_base_classes(
209209
void java_string_library_preprocesst::add_string_type(
210210
const irep_idt &class_name, symbol_tablet &symbol_table)
211211
{
212-
java_class_typet string_type;
213-
string_type.set_tag(class_name);
214-
string_type.set_name("java::" + id2string(class_name));
212+
irep_idt class_symbol_name = "java::" + id2string(class_name);
213+
symbolt tmp_string_symbol;
214+
tmp_string_symbol.name = class_symbol_name;
215+
symbolt *string_symbol = nullptr;
216+
bool already_exists = symbol_table.move(tmp_string_symbol, string_symbol);
217+
218+
if(already_exists)
219+
{
220+
// A library has already defined this type -- we'll replace its
221+
// components with those required for internal string modelling, but
222+
// otherwise leave it alone.
223+
to_java_class_type(string_symbol->type).components().clear();
224+
}
225+
else
226+
{
227+
// No definition of this type exists -- define it as it usually occurs in
228+
// the JDK:
229+
java_class_typet new_string_type;
230+
new_string_type.set_tag(class_name);
231+
new_string_type.set_name(class_symbol_name);
232+
new_string_type.set_access(ID_public);
233+
new_string_type.add_base(struct_tag_typet("java::java.lang.Object"));
234+
235+
std::vector<irep_idt> bases = get_string_type_base_classes(class_name);
236+
for(const irep_idt &base_name : bases)
237+
new_string_type.add_base(
238+
struct_tag_typet("java::" + id2string(base_name)));
239+
240+
string_symbol->base_name = id2string(class_name);
241+
string_symbol->pretty_name = id2string(class_name);
242+
string_symbol->type = new_string_type;
243+
string_symbol->is_type = true;
244+
string_symbol->mode = ID_java;
245+
}
246+
247+
auto &string_type = to_java_class_type(string_symbol->type);
248+
215249
string_type.components().resize(3);
216250
string_type.components()[0].set_name("@java.lang.Object");
217251
string_type.components()[0].set_pretty_name("@java.lang.Object");
@@ -223,22 +257,6 @@ void java_string_library_preprocesst::add_string_type(
223257
string_type.components()[2].set_name("data");
224258
string_type.components()[2].set_pretty_name("data");
225259
string_type.components()[2].type() = pointer_type(java_char_type());
226-
string_type.set_access(ID_public);
227-
string_type.add_base(struct_tag_typet("java::java.lang.Object"));
228-
229-
std::vector<irep_idt> bases = get_string_type_base_classes(class_name);
230-
for(const irep_idt &base_name : bases)
231-
string_type.add_base(struct_tag_typet("java::" + id2string(base_name)));
232-
233-
symbolt tmp_string_symbol;
234-
tmp_string_symbol.name="java::"+id2string(class_name);
235-
symbolt *string_symbol=nullptr;
236-
symbol_table.move(tmp_string_symbol, string_symbol);
237-
string_symbol->base_name=id2string(class_name);
238-
string_symbol->pretty_name=id2string(class_name);
239-
string_symbol->type=string_type;
240-
string_symbol->is_type=true;
241-
string_symbol->mode = ID_java;
242260
}
243261

244262
/// calls string_refine_preprocesst::process_operands with a list of parameters.

jbmc/unit/java_bytecode/java_object_factory/gen_nondet_string_init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ SCENARIO(
4343

4444
// Add java.lang.String to symbol table
4545
java_string_library_preprocesst preprocess;
46+
preprocess.initialize_known_type_table();
4647
preprocess.add_string_type("java.lang.String", symbol_table);
4748
namespacet ns(symbol_table);
4849

jbmc/unit/java_bytecode/java_string_library_preprocess/convert_exprt_to_string_exprt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ TEST_CASE("Convert exprt to string exprt")
3939
namespacet ns(symbol_table);
4040
code_blockt code;
4141
java_string_library_preprocesst preprocess;
42+
preprocess.initialize_known_type_table();
4243
preprocess.add_string_type("java.lang.String", symbol_table);
4344
struct_tag_typet java_string_type("java::java.lang.String");
4445
symbol_exprt expr("a", pointer_type(java_string_type));

0 commit comments

Comments
 (0)