@@ -2094,34 +2094,52 @@ void java_bytecode_convert_methodt::convert_invoke(
2094
2094
const bool is_virtual (
2095
2095
statement == " invokevirtual" || statement == " invokeinterface" );
2096
2096
2097
+ const irep_idt &invoked_method_id = arg0.get (ID_identifier);
2098
+ INVARIANT (
2099
+ !invoked_method_id.empty (),
2100
+ " invoke statement arg0 must have an identifier" );
2101
+
2102
+ auto method_symbol = symbol_table.symbols .find (invoked_method_id);
2103
+
2104
+ // Use the most precise type available: the actual symbol has generic info,
2105
+ // whereas the type given by the invoke instruction doesn't and is therefore
2106
+ // less accurate.
2107
+ if (method_symbol != symbol_table.symbols .end ())
2108
+ arg0.type () = to_java_method_type (method_symbol->second .type );
2109
+
2110
+ // Note arg0 and arg0.type() are subject to many side-effects in this method,
2111
+ // then finally used to populate the call instruction.
2097
2112
java_method_typet &method_type = to_java_method_type (arg0.type ());
2113
+
2098
2114
java_method_typet::parameterst ¶meters (method_type.parameters ());
2099
2115
2100
2116
if (use_this)
2101
2117
{
2118
+ irep_idt classname = arg0.get (ID_C_class);
2119
+
2102
2120
if (parameters.empty () || !parameters[0 ].get_this ())
2103
2121
{
2104
- irep_idt classname = arg0.get (ID_C_class);
2105
2122
typet thistype = struct_tag_typet (classname);
2106
- // Note invokespecial is used for super-method calls as well as
2107
- // constructors.
2108
- if (statement == " invokespecial" )
2109
- {
2110
- if (is_constructor (arg0.get (ID_identifier)))
2111
- {
2112
- if (needed_lazy_methods)
2113
- needed_lazy_methods->add_needed_class (classname);
2114
- method_type.set_is_constructor ();
2115
- }
2116
- else
2117
- method_type.set (ID_java_super_method_call, true );
2118
- }
2119
2123
reference_typet object_ref_type = java_reference_type (thistype);
2120
2124
java_method_typet::parametert this_p (object_ref_type);
2121
2125
this_p.set_this ();
2122
2126
this_p.set_base_name (ID_this);
2123
2127
parameters.insert (parameters.begin (), this_p);
2124
2128
}
2129
+
2130
+ // Note invokespecial is used for super-method calls as well as
2131
+ // constructors.
2132
+ if (statement == " invokespecial" )
2133
+ {
2134
+ if (is_constructor (invoked_method_id))
2135
+ {
2136
+ if (needed_lazy_methods)
2137
+ needed_lazy_methods->add_needed_class (classname);
2138
+ method_type.set_is_constructor ();
2139
+ }
2140
+ else
2141
+ method_type.set (ID_java_super_method_call, true );
2142
+ }
2125
2143
}
2126
2144
2127
2145
code_function_callt call;
@@ -2184,18 +2202,17 @@ void java_bytecode_convert_methodt::convert_invoke(
2184
2202
// accessible from the original caller, but not from the generated test.
2185
2203
// Therefore we must assume that the method is not accessible.
2186
2204
// We set opaque methods as final to avoid assuming they can be overridden.
2187
- irep_idt id = arg0.get (ID_identifier);
2188
2205
if (
2189
- symbol_table. symbols . find (id) == symbol_table.symbols .end () &&
2206
+ method_symbol == symbol_table.symbols .end () &&
2190
2207
!(is_virtual &&
2191
2208
is_method_inherited (arg0.get (ID_C_class), arg0.get (ID_component_name))))
2192
2209
{
2193
2210
symbolt symbol;
2194
- symbol.name = id ;
2211
+ symbol.name = invoked_method_id ;
2195
2212
symbol.base_name = arg0.get (ID_C_base_name);
2196
2213
symbol.pretty_name = id2string (arg0.get (ID_C_class)).substr (6 ) + " ." +
2197
2214
id2string (symbol.base_name ) + " ()" ;
2198
- symbol.type = arg0. type () ;
2215
+ symbol.type = method_type ;
2199
2216
symbol.type .set (ID_access, ID_private);
2200
2217
to_java_method_type (symbol.type ).set_is_final (true );
2201
2218
symbol.value .make_nil ();
@@ -2220,10 +2237,10 @@ void java_bytecode_convert_methodt::convert_invoke(
2220
2237
else
2221
2238
{
2222
2239
// static binding
2223
- call.function () = symbol_exprt (arg0. get (ID_identifier), arg0. type () );
2240
+ call.function () = symbol_exprt (invoked_method_id, method_type );
2224
2241
if (needed_lazy_methods)
2225
2242
{
2226
- needed_lazy_methods->add_needed_method (arg0. get (ID_identifier) );
2243
+ needed_lazy_methods->add_needed_method (invoked_method_id );
2227
2244
// Calling a static method causes static initialization:
2228
2245
needed_lazy_methods->add_needed_class (arg0.get (ID_C_class));
2229
2246
}
0 commit comments