Skip to content

Commit f68e817

Browse files
mgudemannMatthias Güdemann
authored and
Matthias Güdemann
committed
Parse LocalVariabletypetable / Signature attributes use in types
Change from descriptor to signature for class / method / field
1 parent 0823f05 commit f68e817

21 files changed

+1009
-47
lines changed

regression/cbmc-java/enum1/test.desc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
enum1.class
33
--java-unwind-enum-static --unwind 3
44
^VERIFICATION SUCCESSFUL$
@@ -7,3 +7,5 @@ enum1.class
77
^Unwinding loop java::enum1.<clinit>:\(\)V.0 iteration 5 \(6 max\) file enum1.java line 6 function java::enum1.<clinit>:\(\)V bytecode-index 78 thread 0$
88
--
99
^warning: ignoring
10+
--
11+
cf. https://diffblue.atlassian.net/browse/TG-611
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
CORE
1+
KNOWNBUG
22
iterator2.class
3-
--cover location --unwind 3 --function iterator2.f
3+
--cover location --unwind 3 --function iterator2.f
44
^EXIT=0$
55
^SIGNAL=0$
66
^.*SATISFIED$
77
--
88
^warning: ignoring
9+
--
10+
https://diffblue.atlassian.net/browse/TG-610
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
CORE
1+
KNOWNBUG
22
DetectSplitPackagesTask.class
33
--show-symbol-table
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
--
8+
cf. https://diffblue.atlassian.net/browse/TG-610

src/java_bytecode/ci_lazy_methods.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ bool ci_lazy_methodst::operator()(
7979
{
8080
const irep_idt methodid="java::"+id2string(classname)+"."+
8181
id2string(method.name)+":"+
82-
id2string(method.signature);
82+
id2string(method.descriptor);
8383
method_worklist2.push_back(methodid);
8484
}
8585
}
@@ -505,4 +505,3 @@ irep_idt ci_lazy_methodst::get_virtual_method_target(
505505
else
506506
return irep_idt();
507507
}
508-

src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Author: Daniel Kroening, [email protected]
2121
#include "java_bytecode_language.h"
2222
#include "java_utils.h"
2323

24+
#include <util/c_types.h>
2425
#include <util/arith_tools.h>
2526
#include <util/namespace.h>
2627
#include <util/std_expr.h>
@@ -101,6 +102,23 @@ void java_bytecode_convert_classt::convert(const classt &c)
101102
}
102103

103104
java_class_typet class_type;
105+
if(c.has_signature)
106+
{
107+
java_generics_class_typet generic_class_type;
108+
#ifdef DEBUG
109+
std::cout << "INFO: found generic class signature "
110+
<< c.signature
111+
<< " in parsed class "
112+
<< c.name << "\n";
113+
#endif
114+
for(auto t : java_generic_type_from_string(id2string(c.name), c.signature))
115+
{
116+
generic_class_type.generic_types()
117+
.push_back(to_java_generic_parameter(t));
118+
}
119+
120+
class_type=generic_class_type;
121+
}
104122

105123
class_type.set_tag(c.name);
106124
class_type.set(ID_base_name, c.name);
@@ -174,7 +192,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
174192
const irep_idt method_identifier=
175193
id2string(qualified_classname)+
176194
"."+id2string(method.name)+
177-
":"+method.signature;
195+
":"+method.descriptor;
178196
// Always run the lazy pre-stage, as it symbol-table
179197
// registers the function.
180198
debug() << "Adding symbol: method '" << method_identifier << "'" << eom;
@@ -195,7 +213,46 @@ void java_bytecode_convert_classt::convert(
195213
symbolt &class_symbol,
196214
const fieldt &f)
197215
{
198-
typet field_type=java_type_from_string(f.signature);
216+
typet field_type;
217+
if(f.has_signature)
218+
{
219+
field_type=java_type_from_string(f.signature, id2string(class_symbol.name));
220+
221+
/// this is for a free type variable, e.g., a field of the form `T f;`
222+
if(is_java_generic_parameter(field_type))
223+
{
224+
#ifdef DEBUG
225+
std::cout << "fieldtype: generic "
226+
<< to_java_generic_parameter(field_type).type_variable()
227+
.get_identifier()
228+
<< " name " << f.name << "\n";
229+
#endif
230+
}
231+
232+
/// this is for a field that holds a generic type, wither with instantiated
233+
/// or with free type variables, e.g., `List<T> l;` or `List<Integer> l;`
234+
else if(is_java_generic_type(field_type))
235+
{
236+
java_generic_typet &with_gen_type=
237+
to_java_generic_type(field_type);
238+
#ifdef DEBUG
239+
std::cout << "fieldtype: generic container type "
240+
<< std::to_string(with_gen_type.generic_type_variables().size())
241+
<< " type " << with_gen_type.id()
242+
<< " name " << f.name
243+
<< " subtype id " << with_gen_type.subtype().id() << "\n";
244+
#endif
245+
field_type=with_gen_type;
246+
}
247+
248+
/// This case is not possible, a field is either a non-instantiated type
249+
/// variable or a generics container type.
250+
INVARIANT(
251+
!is_java_generic_inst_parameter(field_type),
252+
"Cannot be an instantiated type variable here.");
253+
}
254+
else
255+
field_type=java_type_from_string(f.descriptor);
199256

200257
// is this a static field?
201258
if(f.is_static)

src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ const exprt java_bytecode_convert_methodt::variable(
252252
/// method conversion just yet. The caller should call
253253
/// java_bytecode_convert_method later to give the symbol/method a body.
254254
/// \par parameters: `class_symbol`: class this method belongs to
255-
/// `method_identifier`: fully qualified method name, including type signature
255+
/// `method_identifier`: fully qualified method name, including type descriptor
256256
/// (e.g. "x.y.z.f:(I)")
257257
/// `m`: parsed method object to convert
258258
/// `symbol_table`: global symbol table (will be modified)
@@ -263,7 +263,18 @@ void java_bytecode_convert_method_lazy(
263263
symbol_tablet &symbol_table)
264264
{
265265
symbolt method_symbol;
266-
typet member_type=java_type_from_string(m.signature);
266+
typet member_type;
267+
if(m.has_signature)
268+
{
269+
#ifdef DEBUG
270+
std::cout << "method " << m.name
271+
<< " has signature " << m.signature << "\n";
272+
#endif
273+
member_type=
274+
java_type_from_string(m.signature, id2string(class_symbol.name));
275+
}
276+
else
277+
member_type=java_type_from_string(m.descriptor);
267278

268279
method_symbol.name=method_identifier;
269280
method_symbol.base_name=m.base_name;
@@ -317,7 +328,7 @@ void java_bytecode_convert_methodt::convert(
317328
// to retrieve the symbol (constructed by java_bytecode_convert_method_lazy)
318329
// associated to the method
319330
const irep_idt method_identifier=
320-
id2string(class_symbol.name)+"."+id2string(m.name)+":"+m.signature;
331+
id2string(class_symbol.name)+"."+id2string(m.name)+":"+m.descriptor;
321332
method_id=method_identifier;
322333

323334
const auto &old_sym=symbol_table.lookup(method_identifier);
@@ -350,7 +361,12 @@ void java_bytecode_convert_methodt::convert(
350361
// Construct a fully qualified name for the parameter v,
351362
// e.g. my.package.ClassName.myMethodName:(II)I::anIntParam, and then a
352363
// symbol_exprt with the parameter and its type
353-
typet t=java_type_from_string(v.signature);
364+
typet t;
365+
if(v.has_signature)
366+
t=java_type_from_string(v.signature, id2string(class_symbol.name));
367+
else
368+
t=java_type_from_string(v.descriptor);
369+
354370
std::ostringstream id_oss;
355371
id_oss << method_id << "::" << v.name;
356372
irep_idt identifier(id_oss.str());

src/java_bytecode/java_bytecode_parse_tree.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ void java_bytecode_parse_treet::classt::swap(
2828
std::swap(other.is_public, is_public);
2929
std::swap(other.is_protected, is_protected);
3030
std::swap(other.is_private, is_private);
31+
std::swap(other.has_signature, has_signature);
32+
std::swap(other.signature, signature);
3133
other.implements.swap(implements);
3234
other.fields.swap(fields);
3335
other.methods.swap(methods);
@@ -151,7 +153,7 @@ void java_bytecode_parse_treet::methodt::output(std::ostream &out) const
151153
out << "synchronized ";
152154

153155
out << name;
154-
out << " : " << signature;
156+
out << " : " << descriptor;
155157

156158
out << '\n';
157159

@@ -188,7 +190,7 @@ void java_bytecode_parse_treet::methodt::output(std::ostream &out) const
188190
for(const auto &v : local_variable_table)
189191
{
190192
out << " " << v.index << ": " << v.name << ' '
191-
<< v.signature << '\n';
193+
<< v.descriptor << '\n';
192194
}
193195

194196
out << '\n';
@@ -212,7 +214,7 @@ void java_bytecode_parse_treet::fieldt::output(std::ostream &out) const
212214
out << "static ";
213215

214216
out << name;
215-
out << " : " << signature << ';';
217+
out << " : " << descriptor << ';';
216218

217219
out << '\n';
218220
}

src/java_bytecode/java_bytecode_parse_tree.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class java_bytecode_parse_treet
5454
class membert
5555
{
5656
public:
57+
std::string descriptor;
58+
bool has_signature;
5759
std::string signature;
5860
irep_idt name;
5961
bool is_public, is_protected, is_private, is_static, is_final;
@@ -62,8 +64,8 @@ class java_bytecode_parse_treet
6264
virtual void output(std::ostream &out) const = 0;
6365

6466
membert():
65-
is_public(false), is_protected(false), is_private(false),
66-
is_static(false), is_final(false)
67+
has_signature(false), is_public(false), is_protected(false),
68+
is_private(false), is_static(false), is_final(false)
6769
{
6870
}
6971
};
@@ -100,6 +102,8 @@ class java_bytecode_parse_treet
100102
{
101103
public:
102104
irep_idt name;
105+
std::string descriptor;
106+
bool has_signature=false;
103107
std::string signature;
104108
std::size_t index;
105109
std::size_t start_pc;
@@ -174,7 +178,8 @@ class java_bytecode_parse_treet
174178

175179
typedef std::list<irep_idt> implementst;
176180
implementst implements;
177-
181+
bool has_signature=false;
182+
std::string signature;
178183
typedef std::list<fieldt> fieldst;
179184
typedef std::list<methodt> methodst;
180185
fieldst fields;

0 commit comments

Comments
 (0)