13
13
#include < util/arith_tools.h>
14
14
#include < util/unicode.h>
15
15
16
+ #include < linking/zero_initializer.h>
17
+
16
18
#include " java_bytecode_typecheck.h"
17
19
#include " java_pointer_casts.h"
18
20
#include " java_types.h"
@@ -163,8 +165,26 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr)
163
165
new_symbol.is_lvalue =true ;
164
166
new_symbol.is_static_lifetime =true ; // These are basically const global data.
165
167
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:
166
183
if (string_refinement_enabled)
167
184
{
185
+ struct_exprt literal_init (new_symbol.type );
186
+ literal_init.move_to_operands (jlo_init);
187
+
168
188
// Initialise the string with a constant utf-16 array:
169
189
symbolt array_symbol;
170
190
array_symbol.name =escaped_symbol_name+" _constarray" ;
@@ -185,18 +205,6 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr)
185
205
if (symbol_table.add (array_symbol))
186
206
throw " failed to add constarray symbol to symtab" ;
187
207
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);
200
208
literal_init.copy_to_operands (
201
209
from_integer (literal_array.operands ().size (),
202
210
jls_struct.components ()[1 ].type ()));
@@ -205,6 +213,32 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr)
205
213
206
214
new_symbol.value =literal_init;
207
215
}
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
+ }
208
242
209
243
if (symbol_table.add (new_symbol))
210
244
{
0 commit comments