Skip to content

Commit fabbd04

Browse files
author
Owen Jones
committed
Give up parsing generic method signature with bound
Bounds on generic type variables are not currently parsed. Previously we were assuming a bound of java.lang.Object. This caused inconsistent types in goto programs. When we find a bounded type variable in a function signature we now give up on trying to parse the generic types and fall back to using the descriptor, which knows about the bounds and gives us type consistency. The problem still occurs when the bounded type variable is defined in a class signature.
1 parent f55bd96 commit fabbd04

9 files changed

+134
-346
lines changed

jbmc/src/java_bytecode/java_types.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,18 @@ typet java_type_from_string(
462462
throw unsupported_java_class_signature_exceptiont(
463463
"Failed to find generic signature closing delimiter");
464464
}
465+
466+
// If there are any bounds between '<' and '>' then we cannot currently
467+
// parse them, so we give up. This only happens when parsing the
468+
// signature, so we'll fall back to the result of parsing the
469+
// descriptor, which will respect the bounds correctly.
470+
const size_t colon_pos = src.find(':');
471+
if(colon_pos != std::string::npos && colon_pos < closing_generic)
472+
{
473+
throw unsupported_java_class_signature_exceptiont(
474+
"Cannot currently parse bounds on generic types");
475+
}
476+
465477
const typet &method_type=java_type_from_string(
466478
src.substr(closing_generic+1, std::string::npos), class_name_prefix);
467479

jbmc/unit/java_bytecode/java_bytecode_parse_generics/BoundedGenericInnerClasses.java

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ class Inner<E>
88
class BoundedInner<NUM extends java.lang.Number>
99
{
1010
NUM elem;
11+
12+
public void f(NUM x) {
13+
}
1114
}
1215

1316
BoundedInner<Integer> belem;
Binary file not shown.

jbmc/unit/java_bytecode/java_bytecode_parse_generics/GenericFunctions.java

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public static <T extends Interface_Implementation> void processUpperBoundClass(G
1717

1818
}
1919

20+
public static <T extends java.lang.Number> void processUpperBoundClass2(T x)
21+
{
22+
23+
}
24+
2025
public static <T extends Interface_Implementation & Interface> void processDoubleUpperBoundClass(Generic<T> x)
2126
{
2227

jbmc/unit/java_bytecode/java_bytecode_parse_generics/parse_bounded_generic_inner_classes.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@ SCENARIO(
6868
to_struct_type(class_symbol.type), "elem");
6969
require_type::require_java_generic_parameter(
7070
elem.type(), boundedinner_name + "::NUM");
71+
72+
std::string method_name =
73+
boundedinner_name + ".f:(Ljava/lang/Number;)V";
74+
REQUIRE(new_symbol_table.has_symbol(method_name));
75+
THEN("The method parameter type should respect its bound")
76+
{
77+
const symbolt &method_symbol =
78+
new_symbol_table.lookup_ref(method_name);
79+
const code_typet &method_type =
80+
require_type::require_code(method_symbol.type);
81+
const code_typet::parametert &param =
82+
require_type::require_parameter(method_type, "x");
83+
require_type::require_java_generic_parameter(
84+
param.type(), boundedinner_name + "::NUM");
85+
86+
// TODO: the bounds are not parsed yet; extend tests when fixed -
87+
// issue TG-1286
88+
}
7189
}
7290
}
7391
}

0 commit comments

Comments
 (0)