Skip to content

Commit 396f66e

Browse files
committed
Init string constants when refine-string disabled
In order that at least ("" instanceof String) passes, we must init the class identifier field, both in the case that java.lang.String is a stub and the case where JDK or something like it was present and defined the type. In the latter case we simply zero-initialize the other fields of String since without refine-string we can't understand them.
1 parent ca11bb3 commit 396f66e

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

src/java_bytecode/java_bytecode_typecheck_expr.cpp

+46-12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Author: Daniel Kroening, [email protected]
1313
#include <util/arith_tools.h>
1414
#include <util/unicode.h>
1515

16+
#include <linking/zero_initializer.h>
17+
1618
#include "java_bytecode_typecheck.h"
1719
#include "java_pointer_casts.h"
1820
#include "java_types.h"
@@ -163,8 +165,26 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr)
163165
new_symbol.is_lvalue=true;
164166
new_symbol.is_static_lifetime=true; // These are basically const global data.
165167

168+
// Regardless of string refinement setting, at least initialize
169+
// the literal with @clsid = String and @lock = false:
170+
symbol_typet jlo_symbol("java::java.lang.Object");
171+
const auto& jlo_struct=to_struct_type(ns.follow(jlo_symbol));
172+
struct_exprt jlo_init(jlo_symbol);
173+
const auto& jls_struct=to_struct_type(ns.follow(string_type));
174+
175+
jlo_init.copy_to_operands(
176+
constant_exprt("java::java.lang.String",
177+
jlo_struct.components()[0].type()));
178+
jlo_init.copy_to_operands(
179+
from_integer(0, jlo_struct.components()[1].type()));
180+
181+
// If string refinement *is* around, populate the actual
182+
// contents as well:
166183
if(string_refinement_enabled)
167184
{
185+
struct_exprt literal_init(new_symbol.type);
186+
literal_init.move_to_operands(jlo_init);
187+
168188
// Initialise the string with a constant utf-16 array:
169189
symbolt array_symbol;
170190
array_symbol.name=escaped_symbol_name+"_constarray";
@@ -185,18 +205,6 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr)
185205
if(symbol_table.add(array_symbol))
186206
throw "failed to add constarray symbol to symtab";
187207

188-
symbol_typet jlo_symbol("java::java.lang.Object");
189-
const auto& jlo_struct=to_struct_type(ns.follow(jlo_symbol));
190-
const auto& jls_struct=to_struct_type(ns.follow(string_type));
191-
192-
struct_exprt literal_init(new_symbol.type);
193-
struct_exprt jlo_init(jlo_symbol);
194-
jlo_init.copy_to_operands(
195-
constant_exprt("java::java.lang.String",
196-
jlo_struct.components()[0].type()));
197-
jlo_init.copy_to_operands(
198-
from_integer(0, jlo_struct.components()[1].type()));
199-
literal_init.move_to_operands(jlo_init);
200208
literal_init.copy_to_operands(
201209
from_integer(literal_array.operands().size(),
202210
jls_struct.components()[1].type()));
@@ -205,6 +213,32 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr)
205213

206214
new_symbol.value=literal_init;
207215
}
216+
else if(jls_struct.components().size()>=1 &&
217+
jls_struct.components()[0].get_name()=="@java.lang.Object")
218+
{
219+
// Case where something defined java.lang.String, so it has
220+
// a proper base class (always java.lang.Object in practical
221+
// JDKs seen so far)
222+
struct_exprt literal_init(new_symbol.type);
223+
literal_init.move_to_operands(jlo_init);
224+
for(const auto &comp : jls_struct.components())
225+
{
226+
if(comp.get_name()=="@java.lang.Object")
227+
continue;
228+
// Other members of JDK's java.lang.String we don't understand
229+
// without string-refinement. Just zero-init them; consider using
230+
// test-gen-like nondet object trees instead.
231+
literal_init.copy_to_operands(
232+
zero_initializer(comp.type(), expr.source_location(), ns));
233+
}
234+
new_symbol.value=literal_init;
235+
}
236+
else if(jls_struct.get_bool(ID_incomplete_class))
237+
{
238+
// Case where java.lang.String was stubbed, and so directly defines
239+
// @class_identifier and @lock:
240+
new_symbol.value=jlo_init;
241+
}
208242

209243
if(symbol_table.add(new_symbol))
210244
{

0 commit comments

Comments
 (0)