Skip to content

Commit 9da84c6

Browse files
author
Matthias Güdemann
committed
Replace calls to array.clone in values for Enum
For Enum classes this replaces calls to clone via a specialized clone method call that allows for explicit unwind bounds depending on the number of enum elements.
1 parent 810210a commit 9da84c6

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,6 +2106,21 @@ void java_bytecode_convert_methodt::convert_invoke(
21062106
code_typet &code_type = to_code_type(arg0.type());
21072107
code_typet::parameterst &parameters(code_type.parameters());
21082108

2109+
const std::string full_method_name = id2string(method_id);
2110+
const size_t method_separator = id2string(method_id).rfind(':');
2111+
const std::string method_name = full_method_name.substr(0, method_separator);
2112+
2113+
const size_t class_separator = method_name.rfind('.');
2114+
const std::string calling_class_name = method_name.substr(0, class_separator);
2115+
2116+
std::string class_type_name = calling_class_name.substr(6);
2117+
std::replace(class_type_name.begin(), class_type_name.end(), '.', '/');
2118+
const auto &enum_clone_symbol = symbol_table.lookup_ref(calling_class_name);
2119+
const bool is_enum_values_clone_call =
2120+
enum_clone_symbol.type.get_bool(ID_enumeration) &&
2121+
(full_method_name ==
2122+
(calling_class_name + ".values:()[L" + class_type_name + ";"));
2123+
21092124
if(use_this)
21102125
{
21112126
if(parameters.empty() || !parameters[0].get_this())
@@ -2197,7 +2212,7 @@ void java_bytecode_convert_methodt::convert_invoke(
21972212
// generate code that may wrongly assume that such a method is
21982213
// accessible if we assume that its access attribute is "more
21992214
// accessible" than it actually is.
2200-
irep_idt id = arg0.get(ID_identifier);
2215+
const irep_idt id = arg0.get(ID_identifier);
22012216
if(
22022217
symbol_table.symbols.find(id) == symbol_table.symbols.end() &&
22032218
!(is_virtual &&
@@ -2220,7 +2235,13 @@ void java_bytecode_convert_methodt::convert_invoke(
22202235
symbol_table.add(symbol);
22212236
}
22222237

2223-
if(is_virtual)
2238+
if(is_enum_values_clone_call)
2239+
{
2240+
const std::string clone_name =
2241+
"java::array[" + calling_class_name + "].clone:()Ljava/lang/Object;";
2242+
call.function() = symbol_exprt(clone_name, arg0.type());
2243+
}
2244+
else if(is_virtual)
22242245
{
22252246
// dynamic binding
22262247
assert(use_this);

0 commit comments

Comments
 (0)