Skip to content

Commit 0422748

Browse files
author
Matthias Güdemann
committed
Add unit test with cycle of size 3 and skipped stack level
1 parent 393fb69 commit 0422748

File tree

7 files changed

+182
-0
lines changed

7 files changed

+182
-0
lines changed
Binary file not shown.
Binary file not shown.

jbmc/unit/java_bytecode/goto_program_generics/MutuallyRecursiveGenerics.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
class Outer<K, V, U> {
2+
class Inner<U> {
3+
Outer<V, K, U> o;
4+
U u;
5+
}
6+
Inner<U> inner;
7+
K key;
8+
V value;
9+
}
10+
class Three<X, E, U> {
11+
Three<U, X, E> rotate;
12+
Three<X, E, U> normal;
13+
X x;
14+
E e;
15+
U u;
16+
}
117
class KeyValue<K, V> {
218
KeyValue<K, V> next;
319
KeyValue<V, K> reverse;
@@ -6,6 +22,8 @@ class KeyValue<K, V> {
622
}
723
class MutuallyRecursiveGenerics {
824
KeyValue<String, Integer> example1;
25+
Three<Byte, Character, Integer> example2;
26+
Outer<Boolean, Byte, Short> example3;
927
void f() {
1028
}
1129
}
Binary file not shown.
Binary file not shown.
Binary file not shown.

jbmc/unit/java_bytecode/goto_program_generics/mutually_recursive_generics.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,169 @@ SCENARIO(
142142
reverse_field, "java::java.lang.Integer", "java::java.lang.String");
143143
}
144144
}
145+
THEN(
146+
"The Object has a field `example2` of type `Three<Byte, Character, "
147+
"Integer>`")
148+
{
149+
const auto &example2_field =
150+
require_goto_statements::require_struct_component_assignment(
151+
tmp_object_name, {}, "example2", "java::Three", {}, entry_point_code);
152+
153+
auto has_x_u_e_fields = [&](
154+
const irep_idt &field,
155+
const irep_idt &x_type,
156+
const irep_idt &e_type,
157+
const irep_idt &u_type) {
158+
require_goto_statements::require_struct_component_assignment(
159+
field, {}, "x", x_type, {}, entry_point_code);
160+
require_goto_statements::require_struct_component_assignment(
161+
field, {}, "e", e_type, {}, entry_point_code);
162+
require_goto_statements::require_struct_component_assignment(
163+
field, {}, "u", u_type, {}, entry_point_code);
164+
};
165+
166+
THEN(
167+
"Object 'example2' has field 'x' of type `Byte`, field `u` of type "
168+
"`Character` and a field `e` of type `Integer`.")
169+
{
170+
has_x_u_e_fields(
171+
example2_field,
172+
"java::java.lang.Byte",
173+
"java::java.lang.Character",
174+
"java::java.lang.Integer");
175+
176+
THEN("`example2` has field `rotate`")
177+
{
178+
const auto &rotate_field =
179+
require_goto_statements::require_struct_component_assignment(
180+
example2_field,
181+
{},
182+
"rotate",
183+
"java::Three",
184+
{},
185+
entry_point_code);
186+
has_x_u_e_fields(
187+
rotate_field,
188+
"java::java.lang.Integer",
189+
"java::java.lang.Byte",
190+
"java::java.lang.Character");
191+
192+
THEN("`rotate` has itself a field `rotate` ... ")
193+
{
194+
const auto &rotate_rec_field =
195+
require_goto_statements::require_struct_component_assignment(
196+
rotate_field,
197+
{},
198+
"rotate",
199+
"java::Three",
200+
{},
201+
entry_point_code);
202+
has_x_u_e_fields(
203+
rotate_rec_field,
204+
"java::java.lang.Character",
205+
"java::java.lang.Integer",
206+
"java::java.lang.Byte");
207+
}
208+
THEN("`rotate` has also a field `normal` ... ")
209+
{
210+
const auto &rotate_normal_field =
211+
require_goto_statements::require_struct_component_assignment(
212+
rotate_field,
213+
{},
214+
"normal",
215+
"java::Three",
216+
{},
217+
entry_point_code);
218+
has_x_u_e_fields(
219+
rotate_normal_field,
220+
"java::java.lang.Integer",
221+
"java::java.lang.Byte",
222+
"java::java.lang.Character");
223+
}
224+
}
225+
THEN("`example2` has field `normal`")
226+
{
227+
const auto &normal_field =
228+
require_goto_statements::require_struct_component_assignment(
229+
example2_field,
230+
{},
231+
"normal",
232+
"java::Three",
233+
{},
234+
entry_point_code);
235+
has_x_u_e_fields(
236+
normal_field,
237+
"java::java.lang.Byte",
238+
"java::java.lang.Character",
239+
"java::java.lang.Integer");
240+
THEN("`normal` has itself a field `normal`")
241+
{
242+
const auto &normal_rec_field =
243+
require_goto_statements::require_struct_component_assignment(
244+
example2_field,
245+
{},
246+
"normal",
247+
"java::Three",
248+
{},
249+
entry_point_code);
250+
has_x_u_e_fields(
251+
normal_rec_field,
252+
"java::java.lang.Byte",
253+
"java::java.lang.Character",
254+
"java::java.lang.Integer");
255+
}
256+
THEN("`normal` has also a field `rotate`")
257+
{
258+
const auto &normal_rotate_field =
259+
require_goto_statements::require_struct_component_assignment(
260+
example2_field,
261+
{},
262+
"rotate",
263+
"java::Three",
264+
{},
265+
entry_point_code);
266+
has_x_u_e_fields(
267+
normal_rotate_field,
268+
"java::java.lang.Integer",
269+
"java::java.lang.Byte",
270+
"java::java.lang.Character");
271+
}
272+
}
273+
}
274+
}
275+
THEN("The Object has a field `example3` of type `Outer<Boolean, Byte>`")
276+
{
277+
const auto &example3_field =
278+
require_goto_statements::require_struct_component_assignment(
279+
tmp_object_name, {}, "example3", "java::Outer", {}, entry_point_code);
280+
281+
has_key_and_value_field(
282+
example3_field, "java::java.lang.Boolean", "java::java.lang.Byte");
283+
284+
THEN("`example3` has a field `inner` of type `Outer.Inner`")
285+
{
286+
const auto &inner_field =
287+
require_goto_statements::require_struct_component_assignment(
288+
example3_field,
289+
{},
290+
"inner",
291+
"java::Outer$Inner",
292+
{},
293+
entry_point_code);
294+
295+
THEN(
296+
"Object 'inner' has field 'key' of type `Outer` with `K` and `V` "
297+
"reversed")
298+
{
299+
const auto &inner_outer_field =
300+
require_goto_statements::require_struct_component_assignment(
301+
inner_field, {}, "o", "java::Outer", {}, entry_point_code);
302+
has_key_and_value_field(
303+
inner_outer_field,
304+
"java::java.lang.Byte",
305+
"java::java.lang.Boolean");
306+
}
307+
}
308+
}
145309
}
146310
}

0 commit comments

Comments
 (0)