Skip to content

Commit b741f33

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 b7c741c commit b741f33

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
@@ -2107,6 +2107,21 @@ void java_bytecode_convert_methodt::convert_invoke(
21072107
code_typet &code_type = to_code_type(arg0.type());
21082108
code_typet::parameterst &parameters(code_type.parameters());
21092109

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

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

0 commit comments

Comments
 (0)