Skip to content

Commit 204437e

Browse files
author
Matthias Güdemann
authored
Merge pull request #2975 from mgudemann/feature/jbmc/local_variables_generic_types
Use generic signature for local variables with entry in LVTT
2 parents 5c9d3dd + 5a0feaa commit 204437e

File tree

5 files changed

+55
-3
lines changed

5 files changed

+55
-3
lines changed

jbmc/src/java_bytecode/java_local_variable_table.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -768,9 +768,20 @@ void java_bytecode_convert_methodt::setup_local_variables(
768768
<< " name " << v.var.name << " v.var.descriptor '"
769769
<< v.var.descriptor << "' holes " << v.holes.size() << eom;
770770
#endif
771-
typet t;
772-
// TODO: might need changing once descriptor/signature issue is resolved
773-
t=java_type_from_string(v.var.descriptor);
771+
772+
const std::string &method_name = id2string(method_id);
773+
const size_t method_name_end = method_name.rfind(":(");
774+
const size_t class_name_end = method_name.rfind('.', method_name_end);
775+
INVARIANT(
776+
method_name_end != std::string::npos &&
777+
class_name_end != std::string::npos,
778+
"A method name has the format class `.` method `:(`signature`)`.");
779+
const std::string class_name = method_name.substr(0, class_name_end);
780+
781+
const typet t = v.var.signature.has_value()
782+
? java_type_from_string_with_exception(
783+
v.var.descriptor, v.var.signature, class_name)
784+
: java_type_from_string(v.var.descriptor);
774785

775786
std::ostringstream id_oss;
776787
id_oss << method_id << "::" << v.var.start_pc << "::" << v.var.name;

jbmc/unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ SRC += java_bytecode/ci_lazy_methods/lazy_load_lambdas.cpp \
3333
java_bytecode/java_bytecode_parse_generics/parse_nested_generics.cpp \
3434
java_bytecode/java_bytecode_parse_generics/parse_recursive_generic_class.cpp \
3535
java_bytecode/java_bytecode_parse_generics/parse_signature_descriptor_mismatch.cpp \
36+
java_bytecode/java_bytecode_parse_generics/parse_lvtt_generic_local_vars.cpp \
3637
java_bytecode/java_bytecode_parse_lambdas/java_bytecode_convert_class_lambda_method_handles.cpp \
3738
java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp \
3839
java_bytecode/java_bytecode_parser/parse_java_annotations.cpp \
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public class GenericLocalVar {
2+
public void f() {
3+
java.util.ArrayList<Double> l = null;
4+
}
5+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for parsing generic local variables from the LVTT
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
#include <java-testing-utils/load_java_class.h>
10+
#include <java-testing-utils/require_type.h>
11+
#include <testing-utils/catch.hpp>
12+
13+
SCENARIO(
14+
"parse_lvtt_generic_local_vars",
15+
"[core][java_bytecode][java_bytecode_parse_generics]")
16+
{
17+
const symbol_tablet &new_symbol_table = load_java_class(
18+
"GenericLocalVar", "./java_bytecode/java_bytecode_parse_generics");
19+
20+
const std::string var_name("java::GenericLocalVar.f:()V::1::l");
21+
REQUIRE(new_symbol_table.has_symbol(var_name));
22+
23+
WHEN("Local variable has an entry in the LVTT")
24+
{
25+
THEN("The type should be generic and instantiated with Double")
26+
{
27+
const symbolt &var_symbol = new_symbol_table.lookup_ref(var_name);
28+
java_generic_typet local_var_type =
29+
require_type::require_java_generic_type(
30+
var_symbol.type,
31+
{{require_type::type_argument_kindt::Inst,
32+
"java::java.lang.Double"}});
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)