Skip to content

[TG-2453] catch unsupported generics exception #1838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions src/java_bytecode/java_bytecode_convert_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,19 @@ void java_bytecode_convert_classt::convert(const classt &c)
extract_generic_superclass_reference(c.signature);
if(superclass_ref.has_value())
{
const java_generic_symbol_typet generic_base(
base, superclass_ref.value(), qualified_classname);
class_type.add_base(generic_base);
try
{
const java_generic_symbol_typet generic_base(
base, superclass_ref.value(), qualified_classname);
class_type.add_base(generic_base);
}
catch(unsupported_java_class_signature_exceptiont)
{
debug() << "unsupported generic superclass signature "
<< id2string(*superclass_ref)
<< " falling back on using the descriptor" << eom;
class_type.add_base(base);
}
}
else
{
Expand All @@ -268,9 +278,19 @@ void java_bytecode_convert_classt::convert(const classt &c)
extract_generic_interface_reference(c.signature, id2string(interface));
if(interface_ref.has_value())
{
const java_generic_symbol_typet generic_base(
base, interface_ref.value(), qualified_classname);
class_type.add_base(generic_base);
try
{
const java_generic_symbol_typet generic_base(
base, interface_ref.value(), qualified_classname);
class_type.add_base(generic_base);
}
catch(unsupported_java_class_signature_exceptiont)
{
debug() << "unsupported generic interface signature "
<< id2string(*interface_ref)
<< " falling back on using the descriptor" << eom;
class_type.add_base(base);
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions unit/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ SRC += unit_tests.cpp \
util/symbol_table.cpp \
catch_example.cpp \
java_bytecode/java_virtual_functions/virtual_functions.cpp \
java_bytecode/java_bytecode_parse_generics/parse_generic_superclasses.cpp \
# Empty last line

INCLUDES= -I ../src/ -I.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,23 @@ public T someMethod() {
return f;
}
}

class GenericBounds extends Generic<Class<?>> {
// references exist only to load these class files, too
GenericBoundsUpper gen_upper;
GenericBoundsLower gen_lower;
GenericInterface gen_interface;

}

class GenericBoundsUpper extends Generic<Class<? extends Class>> {
}

class GenericBoundsLower extends Generic<Class<? super Class>> {
}

class GenericInterface implements InterfaceGeneric<Class<? extends Class>> {
public Class<? extends Class> someMethod(){
return null;
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*******************************************************************\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file needs adding to the unit/Makefile


Module: Unit tests for parsing classes with generic superclasses or interfaces
with unsupported signatures, falling back to using the raw type
descriptors

Author: DiffBlue Limited. All rights reserved.

\*******************************************************************/

#include <testing-utils/catch.hpp>
#include <testing-utils/load_java_class.h>
#include <testing-utils/require_type.h>

SCENARIO(
"parse generic superclass signature",
"[core][java_byte code[java_bytecode_parse_generics]]")
{
const symbol_tablet &new_symbol_table = load_java_class(
"GenericBounds", "./java_bytecode/java_bytecode_parse_generics");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file appears to be new but is missing from the PR


const std::string base_generic = "java::Generic";
const irep_idt base_generic_interface = "java::InterfaceGeneric";

const std::string load_class("java::GenericBounds");
THEN(
"these fields have a non-generic base class / interface as their real "
"generic signature is unsupported at the moment")
{
// once bounds in generic signatures are supported, this test must be
// changed to check for the correct generic types, TODO(mgudemann),
// cf. TG-1286, TG-675
{
const symbolt &upper_symbol =
new_symbol_table.lookup_ref("java::GenericBoundsUpper");
const java_class_typet &upper_type =
to_java_class_type(upper_symbol.type);
REQUIRE(upper_type.bases().size() == 1);
const symbol_typet base_type = require_type::require_symbol(
upper_type.bases().at(0).type(), base_generic);
REQUIRE_FALSE(is_java_generic_symbol_type(base_type));
}
{
const symbolt &lower_symbol =
new_symbol_table.lookup_ref("java::GenericBoundsLower");
const java_class_typet &lower_type =
to_java_class_type(lower_symbol.type);
REQUIRE(lower_type.bases().size() == 1);
const symbol_typet base_type = require_type::require_symbol(
lower_type.bases().at(0).type(), base_generic);
REQUIRE_FALSE(is_java_generic_symbol_type(base_type));
}
{
const symbolt &interface_symbol =
new_symbol_table.lookup_ref("java::GenericInterface");
const java_class_typet &interface_type =
to_java_class_type(interface_symbol.type);
REQUIRE(interface_type.bases().size() == 2);
const symbol_typet base_type = require_type::require_symbol(
interface_type.bases().at(1).type(), base_generic_interface);
REQUIRE_FALSE(is_java_generic_symbol_type(base_type));
}
}
}