diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 8b45d2692a1..2355de33bec 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -112,8 +112,10 @@ extract_generic_superclass_reference(const optionalt &signature) signature.value().substr(start, (end - start) + 1); // if the superclass is generic then the reference is of form - // Lsuperclass-name; - if(has_suffix(superclass_ref, ">;")) + // `Lsuperclass-name;` if it is implicitly generic, then the + // reference is of the form + // `Lsuperclass-name.Innerclass-Name` + if(superclass_ref.find('<') != std::string::npos) return superclass_ref; } return {}; diff --git a/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.class b/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.class index bd6fb9644fe..5943ed714d8 100644 Binary files a/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.class and b/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java b/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java index caf7bd5e178..14aa3ecef53 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java +++ b/unit/java_bytecode/java_bytecode_parse_generics/DerivedGenerics.java @@ -15,6 +15,9 @@ public class DerivedGenerics { ExtendsAndImplementsSameInterface new14; ExtendsAndImplementsSameInterface2 new15; ExtendsAndImplementsSameInterfaceGeneric new16; + GenericBase.ExtendImplicit new17; + GenericBase.ExtendImplicitAndExplicit new18; + GenericBase2.ExtendImplicitAndExplicit new19; } class DerivedGenericInst extends Generic @@ -189,3 +192,25 @@ public Class someMethod(){ return null; } } + +// This class exists to test that subclasses of implicit generic classes have a +// base class entry which is a Java generic symbol. +class GenericBase { + class ImplicitGeneric { + } + class ExtendImplicit extends ImplicitGeneric { + } + class ImplicitAndExplicitGeneric { + } + class ExtendImplicitAndExplicit extends ImplicitAndExplicitGeneric { + } +} + +// This class exists to test the subclasses of generic and implicitly generic +// classes have a base class entry which is a Java generic symbol. +class GenericBase2 { + class ImplicitAndExplicitGeneric { + } + class ExtendImplicitAndExplicit extends ImplicitAndExplicitGeneric { + } +} diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ExtendImplicit.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ExtendImplicit.class new file mode 100644 index 00000000000..928ee536ca0 Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ExtendImplicit.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ExtendImplicitAndExplicit.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ExtendImplicitAndExplicit.class new file mode 100644 index 00000000000..00166f7d94f Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ExtendImplicitAndExplicit.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ImplicitAndExplicitGeneric.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ImplicitAndExplicitGeneric.class new file mode 100644 index 00000000000..c2e509fa680 Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ImplicitAndExplicitGeneric.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ImplicitGeneric.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ImplicitGeneric.class new file mode 100644 index 00000000000..a4b8953527b Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase$ImplicitGeneric.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase.class new file mode 100644 index 00000000000..ccce4e1d77a Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2$ExtendImplicitAndExplicit.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2$ExtendImplicitAndExplicit.class new file mode 100644 index 00000000000..358f4bc35a4 Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2$ExtendImplicitAndExplicit.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2$ImplicitAndExplicitGeneric.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2$ImplicitAndExplicitGeneric.class new file mode 100644 index 00000000000..3704ae8c793 Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2$ImplicitAndExplicitGeneric.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2.class b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2.class new file mode 100644 index 00000000000..7c2d9b77cd2 Binary files /dev/null and b/unit/java_bytecode/java_bytecode_parse_generics/GenericBase2.class differ diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp index 6c00ae92065..3095615b8fb 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp @@ -559,4 +559,68 @@ SCENARIO( // TODO: Check that specialised superclass is created. TG-1418, TG-1419 } + + THEN("There should be a symbol for the `ExtendImplicit` class") + { + std::string class_prefix = "java::GenericBase$ExtendImplicit"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); + const class_typet &derived_class_type = + require_type::require_java_implicitly_generic_class(derived_symbol.type); + + THEN("The base for superclass is implicitly generic") + { + REQUIRE(derived_class_type.bases().size() == 1); + const typet &base_type = derived_class_type.bases().at(0).type(); + require_type::require_java_generic_symbol_type( + base_type, + "java::GenericBase$ImplicitGeneric", + {{require_type::type_argument_kindt::Var, "java::GenericBase::T"}}); + } + } + + THEN("There should be a symbol for the `ExtendImplicitAndExplicit` class") + { + std::string class_prefix = "java::GenericBase$ExtendImplicitAndExplicit"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); + const class_typet &derived_class_type = + require_type::require_java_implicitly_generic_class(derived_symbol.type); + + THEN("The base for superclass is generic *and* implicitly generic") + { + REQUIRE(derived_class_type.bases().size() == 1); + const typet &base_type = derived_class_type.bases().at(0).type(); + require_type::require_java_generic_symbol_type( + base_type, + "java::GenericBase$ImplicitAndExplicitGeneric", + {{require_type::type_argument_kindt::Var, "java::GenericBase::T"}, + {require_type::type_argument_kindt::Var, + "java::GenericBase$ExtendImplicitAndExplicit::S"}}); + } + } + + THEN("There should be a symbol for the `ExtendImplicitAndExplicit` class") + { + std::string class_prefix = "java::GenericBase2$ExtendImplicitAndExplicit"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); + const class_typet &derived_class_type = + require_type::require_java_implicitly_generic_class(derived_symbol.type); + + THEN("The base for superclass is generic *and* implicitly generic") + { + REQUIRE(derived_class_type.bases().size() == 1); + const typet &base_type = derived_class_type.bases().at(0).type(); + require_type::require_java_generic_symbol_type( + base_type, + "java::GenericBase2$ImplicitAndExplicitGeneric", + {{require_type::type_argument_kindt::Var, "java::GenericBase2::T"}, + {require_type::type_argument_kindt::Var, "java::GenericBase2::S"}, + {require_type::type_argument_kindt::Var, "java::GenericBase2::S"}}); + } + } }