Skip to content

Commit 0b17511

Browse files
author
Thomas Kiley
authored
Merge pull request #1955 from svorenova/bugfix_tg2842
[TG-2842] Specialization for mocked and unsupported generics
2 parents eb1ac7b + 076aa5a commit 0b17511

File tree

61 files changed

+596
-170
lines changed

Some content is hidden

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

61 files changed

+596
-170
lines changed

src/java_bytecode/generic_parameter_specialization_map_keys.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,21 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_pointer(
9999
pointer_type.subtype().get(ID_identifier) ==
100100
pointer_subtype_struct.get(ID_name));
101101

102-
const java_generic_typet &generic_pointer =
103-
to_java_generic_type(pointer_type);
104-
105-
// If the pointer points to an incomplete class, don't treat the generics
106-
if(!pointer_subtype_struct.get_bool(ID_incomplete_class))
102+
// If the pointer points to:
103+
// - an incomplete class or
104+
// - a class that is neither generic nor implicitly generic (this
105+
// may be due to unsupported class signature)
106+
// then ignore the generic types in the pointer and do not add any pairs.
107+
// TODO TG-1996 should decide how mocking and generics should work
108+
// together. Currently an incomplete class is never marked as generic. If
109+
// this changes in TG-1996 then the condition below should be updated.
110+
if(
111+
!pointer_subtype_struct.get_bool(ID_incomplete_class) &&
112+
(is_java_generic_class_type(pointer_subtype_struct) ||
113+
is_java_implicitly_generic_class_type(pointer_subtype_struct)))
107114
{
108-
PRECONDITION(
109-
is_java_generic_class_type(pointer_subtype_struct) ||
110-
is_java_implicitly_generic_class_type(pointer_subtype_struct));
115+
const java_generic_typet &generic_pointer =
116+
to_java_generic_type(pointer_type);
111117
const std::vector<java_generic_parametert> &generic_parameters =
112118
get_all_generic_parameters(pointer_subtype_struct);
113119

@@ -135,14 +141,23 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_symbol(
135141
const symbol_typet &symbol_type,
136142
const typet &symbol_struct)
137143
{
138-
if(is_java_generic_symbol_type(symbol_type))
144+
// If the struct is:
145+
// - an incomplete class or
146+
// - a class that is neither generic nor implicitly generic (this
147+
// may be due to unsupported class signature)
148+
// then ignore the generic types in the symbol_type and do not add any pairs.
149+
// TODO TG-1996 should decide how mocking and generics should work
150+
// together. Currently an incomplete class is never marked as generic. If
151+
// this changes in TG-1996 then the condition below should be updated.
152+
if(
153+
is_java_generic_symbol_type(symbol_type) &&
154+
!symbol_struct.get_bool(ID_incomplete_class) &&
155+
(is_java_generic_class_type(symbol_struct) ||
156+
is_java_implicitly_generic_class_type(symbol_struct)))
139157
{
140-
java_generic_symbol_typet generic_symbol =
158+
const java_generic_symbol_typet &generic_symbol =
141159
to_java_generic_symbol_type(symbol_type);
142160

143-
PRECONDITION(
144-
is_java_generic_class_type(symbol_struct) ||
145-
is_java_implicitly_generic_class_type(symbol_struct));
146161
const std::vector<java_generic_parametert> &generic_parameters =
147162
get_all_generic_parameters(symbol_struct);
148163

src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,12 @@ void java_bytecode_convert_classt::convert(const classt &c)
202202
}
203203
class_type=generic_class_type;
204204
}
205-
catch(unsupported_java_class_signature_exceptiont)
205+
catch(const unsupported_java_class_signature_exceptiont &e)
206206
{
207-
warning() << "we currently don't support parsing for example double "
208-
"bounded, recursive and wild card generics" << eom;
207+
warning() << "Class: " << c.name
208+
<< "\n could not parse signature: " << c.signature.value()
209+
<< "\n " << e.what() << "\n ignoring that the class is generic"
210+
<< eom;
209211
}
210212
}
211213

@@ -253,11 +255,12 @@ void java_bytecode_convert_classt::convert(const classt &c)
253255
base, superclass_ref.value(), qualified_classname);
254256
class_type.add_base(generic_base);
255257
}
256-
catch(unsupported_java_class_signature_exceptiont)
258+
catch(const unsupported_java_class_signature_exceptiont &e)
257259
{
258-
debug() << "unsupported generic superclass signature "
259-
<< id2string(*superclass_ref)
260-
<< " falling back on using the descriptor" << eom;
260+
warning() << "Superclass: " << c.extends << " of class: " << c.name
261+
<< "\n could not parse signature: " << superclass_ref.value()
262+
<< "\n " << e.what()
263+
<< "\n ignoring that the superclass is generic" << eom;
261264
class_type.add_base(base);
262265
}
263266
}
@@ -292,11 +295,12 @@ void java_bytecode_convert_classt::convert(const classt &c)
292295
base, interface_ref.value(), qualified_classname);
293296
class_type.add_base(generic_base);
294297
}
295-
catch(unsupported_java_class_signature_exceptiont)
298+
catch(const unsupported_java_class_signature_exceptiont &e)
296299
{
297-
debug() << "unsupported generic interface signature "
298-
<< id2string(*interface_ref)
299-
<< " falling back on using the descriptor" << eom;
300+
warning() << "Interface: " << interface << " of class: " << c.name
301+
<< "\n could not parse signature: " << interface_ref.value()
302+
<< "\n " << e.what()
303+
<< "\n ignoring that the interface is generic" << eom;
300304
class_type.add_base(base);
301305
}
302306
}

src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,21 @@ code_typet member_type_lazy(
286286
}
287287
else
288288
{
289-
message.warning() << "method: " << class_name << "." << method_name
290-
<< "\n signature: " << signature.value() << "\n descriptor: "
291-
<< descriptor << "\n different number of parameters, reverting to "
292-
"descriptor" << message.eom;
289+
message.warning() << "Method: " << class_name << "." << method_name
290+
<< "\n signature: " << signature.value()
291+
<< "\n descriptor: " << descriptor
292+
<< "\n different number of parameters, reverting to "
293+
"descriptor"
294+
<< message.eom;
293295
}
294296
}
295-
catch(unsupported_java_class_signature_exceptiont &e)
297+
catch(const unsupported_java_class_signature_exceptiont &e)
296298
{
297-
message.warning() << "method: " << class_name << "." << method_name
298-
<< "\n could not parse signature: " << signature.value() << "\n "
299-
<< e.what() << "\n" << " reverting to descriptor: "
300-
<< descriptor << message.eom;
299+
message.warning() << "Method: " << class_name << "." << method_name
300+
<< "\n could not parse signature: " << signature.value()
301+
<< "\n " << e.what() << "\n"
302+
<< " reverting to descriptor: " << descriptor
303+
<< message.eom;
301304
}
302305
}
303306
return to_code_type(member_type_from_descriptor);

unit/goto-programs/goto_program_generics/GenericBases.java

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
1-
// Helper classes
2-
class Wrapper<T> {
3-
public T field;
4-
}
5-
6-
class IntWrapper {
7-
public int i;
8-
}
9-
10-
class TwoWrapper<K, V> {
11-
public K first;
12-
public V second;
13-
}
14-
15-
interface InterfaceWrapper<T> {
16-
public T method(T t);
17-
}
18-
191
// A class extending a generic class instantiated with a standard library class
202
class SuperclassInst extends Wrapper<Integer> {
213
public void foo() {
@@ -24,14 +6,14 @@ public void foo() {
246
}
257

268
// A class extending a generic class instantiated with a user-defined class
27-
class SuperclassInst2 extends Wrapper<IntWrapper> {
9+
class SuperclassInst2 extends Wrapper<IWrapper> {
2810
public void foo() {
2911
this.field.i = 5;
3012
}
3113
}
3214

3315
// A class extending an instantiated nested generic class
34-
class SuperclassInst3 extends Wrapper<Wrapper<IntWrapper>> {
16+
class SuperclassInst3 extends Wrapper<Wrapper<IWrapper>> {
3517
public void foo() {
3618
this.field.field.i = 5;
3719
}
@@ -54,7 +36,7 @@ public void foo() {
5436

5537
// A generic class extending a generic class with both instantiated and
5638
// uninstantiated parameters
57-
class SuperclassMixed<U> extends TwoWrapper<U,IntWrapper> {
39+
class SuperclassMixed<U> extends PairWrapper<U,IWrapper> {
5840
public void foo(U value) {
5941
this.first = value;
6042
this.second.i = 5;
@@ -99,7 +81,7 @@ public void foo(U value) {
9981
}
10082
public Inner inner;
10183

102-
class InnerGen<T> extends TwoWrapper<U,T> {
84+
class InnerGen<T> extends PairWrapper<U,T> {
10385
public void foo(U uvalue, T tvalue) {
10486
this.first = uvalue;
10587
this.second = tvalue;
@@ -113,11 +95,23 @@ class InnerThree extends Inner {
11395
}
11496
class SuperclassInnerUninstTest
11597
{
116-
SuperclassInnerUninst<IntWrapper> f;
98+
SuperclassInnerUninst<IWrapper> f;
11799
public void foo() {
118-
IntWrapper x = new IntWrapper();
100+
IWrapper x = new IWrapper(0);
119101
f.inner.foo(x);
120102
f.inner_gen.foo(x,true);
121103
f.inner_three.foo(x);
122104
}
123105
}
106+
107+
class SuperclassUnsupported extends UnsupportedWrapper1<SuperclassUnsupported> {
108+
public void foo() {
109+
this.field = new SuperclassUnsupported();
110+
}
111+
}
112+
113+
class SuperclassOpaque extends OpaqueWrapper<IWrapper> {
114+
public void foo() {
115+
this.field.i = 5;
116+
}
117+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)