Skip to content

Commit 4d3ab7a

Browse files
author
Matthias Güdemann
authored
Merge pull request diffblue#1838 from mgudemann/bugfix/catch_unsupported_generics_exception
[TG-2453] catch unsupported generics exception
2 parents a8bdb09 + 7070296 commit 4d3ab7a

File tree

8 files changed

+111
-6
lines changed

8 files changed

+111
-6
lines changed

src/java_bytecode/java_bytecode_convert_class.cpp

+26-6
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,19 @@ void java_bytecode_convert_classt::convert(const classt &c)
239239
extract_generic_superclass_reference(c.signature);
240240
if(superclass_ref.has_value())
241241
{
242-
const java_generic_symbol_typet generic_base(
243-
base, superclass_ref.value(), qualified_classname);
244-
class_type.add_base(generic_base);
242+
try
243+
{
244+
const java_generic_symbol_typet generic_base(
245+
base, superclass_ref.value(), qualified_classname);
246+
class_type.add_base(generic_base);
247+
}
248+
catch(unsupported_java_class_signature_exceptiont)
249+
{
250+
debug() << "unsupported generic superclass signature "
251+
<< id2string(*superclass_ref)
252+
<< " falling back on using the descriptor" << eom;
253+
class_type.add_base(base);
254+
}
245255
}
246256
else
247257
{
@@ -268,9 +278,19 @@ void java_bytecode_convert_classt::convert(const classt &c)
268278
extract_generic_interface_reference(c.signature, id2string(interface));
269279
if(interface_ref.has_value())
270280
{
271-
const java_generic_symbol_typet generic_base(
272-
base, interface_ref.value(), qualified_classname);
273-
class_type.add_base(generic_base);
281+
try
282+
{
283+
const java_generic_symbol_typet generic_base(
284+
base, interface_ref.value(), qualified_classname);
285+
class_type.add_base(generic_base);
286+
}
287+
catch(unsupported_java_class_signature_exceptiont)
288+
{
289+
debug() << "unsupported generic interface signature "
290+
<< id2string(*interface_ref)
291+
<< " falling back on using the descriptor" << eom;
292+
class_type.add_base(base);
293+
}
274294
}
275295
else
276296
{

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ SRC += unit_tests.cpp \
4545
util/symbol_table.cpp \
4646
catch_example.cpp \
4747
java_bytecode/java_virtual_functions/virtual_functions.cpp \
48+
java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp \
4849
# Empty last line
4950

5051
INCLUDES= -I ../src/ -I.

unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java

+20
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,23 @@ public T someMethod() {
169169
return f;
170170
}
171171
}
172+
173+
class GenericBounds extends Generic<Class<?>> {
174+
// references exist only to load these class files, too
175+
GenericBoundsUpper gen_upper;
176+
GenericBoundsLower gen_lower;
177+
GenericInterface gen_interface;
178+
179+
}
180+
181+
class GenericBoundsUpper extends Generic<Class<? extends Class>> {
182+
}
183+
184+
class GenericBoundsLower extends Generic<Class<? super Class>> {
185+
}
186+
187+
class GenericInterface implements InterfaceGeneric<Class<? extends Class>> {
188+
public Class<? extends Class> someMethod(){
189+
return null;
190+
}
191+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for parsing classes with generic superclasses or interfaces
4+
with unsupported signatures, falling back to using the raw type
5+
descriptors
6+
7+
Author: DiffBlue Limited. All rights reserved.
8+
9+
\*******************************************************************/
10+
11+
#include <testing-utils/catch.hpp>
12+
#include <testing-utils/load_java_class.h>
13+
#include <testing-utils/require_type.h>
14+
15+
SCENARIO(
16+
"parse generic superclass signature",
17+
"[core][java_byte code[java_bytecode_parse_generics]]")
18+
{
19+
const symbol_tablet &new_symbol_table = load_java_class(
20+
"GenericBounds", "./java_bytecode/java_bytecode_parse_generics");
21+
22+
const std::string base_generic = "java::Generic";
23+
const irep_idt base_generic_interface = "java::InterfaceGeneric";
24+
25+
const std::string load_class("java::GenericBounds");
26+
THEN(
27+
"these fields have a non-generic base class / interface as their real "
28+
"generic signature is unsupported at the moment")
29+
{
30+
// once bounds in generic signatures are supported, this test must be
31+
// changed to check for the correct generic types, TODO(mgudemann),
32+
// cf. TG-1286, TG-675
33+
{
34+
const symbolt &upper_symbol =
35+
new_symbol_table.lookup_ref("java::GenericBoundsUpper");
36+
const java_class_typet &upper_type =
37+
to_java_class_type(upper_symbol.type);
38+
REQUIRE(upper_type.bases().size() == 1);
39+
const symbol_typet base_type = require_type::require_symbol(
40+
upper_type.bases().at(0).type(), base_generic);
41+
REQUIRE_FALSE(is_java_generic_symbol_type(base_type));
42+
}
43+
{
44+
const symbolt &lower_symbol =
45+
new_symbol_table.lookup_ref("java::GenericBoundsLower");
46+
const java_class_typet &lower_type =
47+
to_java_class_type(lower_symbol.type);
48+
REQUIRE(lower_type.bases().size() == 1);
49+
const symbol_typet base_type = require_type::require_symbol(
50+
lower_type.bases().at(0).type(), base_generic);
51+
REQUIRE_FALSE(is_java_generic_symbol_type(base_type));
52+
}
53+
{
54+
const symbolt &interface_symbol =
55+
new_symbol_table.lookup_ref("java::GenericInterface");
56+
const java_class_typet &interface_type =
57+
to_java_class_type(interface_symbol.type);
58+
REQUIRE(interface_type.bases().size() == 2);
59+
const symbol_typet base_type = require_type::require_symbol(
60+
interface_type.bases().at(1).type(), base_generic_interface);
61+
REQUIRE_FALSE(is_java_generic_symbol_type(base_type));
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)