Skip to content

Commit 2348d10

Browse files
author
thk123
committed
Adding unit test for checking local lambda conversion
Verifies the structure mimics the construction of an anonymous class that implements the interface
1 parent 46fa176 commit 2348d10

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SRC += unit_tests.cpp \
2121
goto-programs/class_hierarchy_graph.cpp \
2222
goto-programs/remove_virtual_functions_without_fallback.cpp \
2323
java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp \
24+
java_bytecode/java_bytecode_convert_method/convert_invoke_dynamic.cpp \
2425
java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp \
2526
java_bytecode/java_object_factory/gen_nondet_string_init.cpp \
2627
java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for converting invokedynamic instructions into codet
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/catch.hpp>
10+
#include <testing-utils/load_java_class.h>
11+
#include <testing-utils/require_goto_statements.h>
12+
#include <testing-utils/require_expr.h>
13+
#include <testing-utils/require_type.h>
14+
#include <testing-utils/run_test_with_compilers.h>
15+
#include <testing-utils/require_symbol.h>
16+
17+
SCENARIO(
18+
"Converting invokedynamic with a local lambda",
19+
"[core]"
20+
"[lamdba][java_bytecode][java_bytecode_convert_method][!mayfail]")
21+
{
22+
// NOLINTNEXTLINE(whitespace/braces)
23+
run_test_with_compilers([](const std::string &compiler) {
24+
GIVEN(
25+
"A class with a static lambda variables from " + compiler + " compiler.")
26+
{
27+
symbol_tablet symbol_table = load_java_class(
28+
"LocalLambdas",
29+
"./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler +
30+
"_classes/",
31+
"LocalLambdas.test");
32+
33+
WHEN("Inspecting the assignments of the entry function")
34+
{
35+
const std::vector<codet> &instructions =
36+
require_goto_statements::get_all_statements(
37+
symbol_table.lookup_ref("java::LocalLambdas.test:()V").value);
38+
39+
THEN("The local variable should be assigned a non-null pointer")
40+
{
41+
// TODO(tkiley): we don't want 11 here
42+
// TODO(tkiley): This is the actual lambda which doesn't currently work
43+
const auto lambda_assignment =
44+
require_goto_statements::find_pointer_assignments(
45+
"java::LocalLambdas.test:()V::11::simpleLambda", instructions);
46+
47+
REQUIRE(lambda_assignment.non_null_assignments.size() == 1);
48+
REQUIRE_FALSE(lambda_assignment.null_assignment.has_value());
49+
50+
const typecast_exprt &rhs_value = require_expr::require_typecast(
51+
lambda_assignment.non_null_assignments[0].rhs());
52+
53+
const symbol_exprt &rhs_symbol =
54+
require_expr::require_symbol(rhs_value.op0());
55+
56+
const irep_idt &tmp_object_symbol = rhs_symbol.get_identifier();
57+
58+
const auto tmp_object_assignments =
59+
require_goto_statements::find_pointer_assignments(
60+
tmp_object_symbol, instructions);
61+
62+
REQUIRE(tmp_object_assignments.non_null_assignments.size() == 1);
63+
REQUIRE_FALSE(tmp_object_assignments.null_assignment.has_value());
64+
65+
const side_effect_exprt &side_effect_expr =
66+
require_expr::require_side_effect_expr(
67+
tmp_object_assignments.non_null_assignments[0].rhs(),
68+
ID_java_new);
69+
70+
const pointer_typet &lambda_temp_type =
71+
require_type::require_pointer(side_effect_expr.type(), {});
72+
73+
const symbol_typet &lambda_implementor_type =
74+
require_type::require_symbol(lambda_temp_type.subtype());
75+
76+
const irep_idt &tmp_class_identifier =
77+
lambda_implementor_type.get_identifier();
78+
79+
const symbolt &lambda_implementor_type_symbol =
80+
require_symbol::require_symbol_exists(
81+
symbol_table, tmp_class_identifier);
82+
83+
REQUIRE(lambda_implementor_type_symbol.is_type);
84+
const class_typet &tmp_lambda_class_type =
85+
require_type::require_complete_class(
86+
lambda_implementor_type_symbol.type);
87+
88+
REQUIRE(tmp_lambda_class_type.has_base("java::SimpleLambda"));
89+
}
90+
}
91+
}
92+
});
93+
}

0 commit comments

Comments
 (0)