Skip to content

Commit 258e3ae

Browse files
author
Matthias Güdemann
committed
Track recursion for generic type parameter definition
1 parent 7360696 commit 258e3ae

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

jbmc/src/java_bytecode/select_pointer_type.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ pointer_typet select_pointer_typet::convert_pointer_type(
3232
// a generic parameter, specialize it with concrete types
3333
if(!generic_parameter_specialization_map.empty())
3434
{
35+
generic_parameter_recursion_trackingt visited;
3536
return specialize_generics(
36-
pointer_type, generic_parameter_specialization_map);
37+
pointer_type, generic_parameter_specialization_map, visited);
3738
}
3839
else
3940
{
@@ -62,7 +63,8 @@ pointer_typet select_pointer_typet::convert_pointer_type(
6263
pointer_typet select_pointer_typet::specialize_generics(
6364
const pointer_typet &pointer_type,
6465
const generic_parameter_specialization_mapt
65-
&generic_parameter_specialization_map) const
66+
&generic_parameter_specialization_map,
67+
generic_parameter_recursion_trackingt &visited_nodes) const
6668
{
6769
if(is_java_generic_parameter(pointer_type))
6870
{
@@ -80,12 +82,21 @@ pointer_typet select_pointer_typet::specialize_generics(
8082
const pointer_typet &type =
8183
generic_parameter_specialization_map.find(parameter_name)->second.back();
8284

85+
// if we have already seen this before, we will not learn any additional
86+
// information from further recursion, only cause a segmentation fault.
87+
if(visited_nodes.find(parameter_name) != visited_nodes.end())
88+
{
89+
throw "no infinite recursion";
90+
}
91+
92+
visited_nodes.insert(parameter_name);
93+
8394
// generic parameters can be adopted from outer classes or superclasses so
8495
// we may need to search for the concrete type recursively
8596
return is_java_generic_parameter(type)
8697
? specialize_generics(
8798
to_java_generic_parameter(type),
88-
generic_parameter_specialization_map)
99+
generic_parameter_specialization_map, visited_nodes)
89100
: type;
90101
}
91102
else if(pointer_type.subtype().id() == ID_symbol)
@@ -99,7 +110,7 @@ pointer_typet select_pointer_typet::specialize_generics(
99110
{
100111
const pointer_typet &new_array_type = specialize_generics(
101112
to_pointer_type(array_element_type),
102-
generic_parameter_specialization_map);
113+
generic_parameter_specialization_map, visited_nodes);
103114

104115
pointer_typet replacement_array_type = java_array_type('a');
105116
replacement_array_type.subtype().set(ID_C_element_type, new_array_type);

jbmc/src/java_bytecode/select_pointer_type.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
typedef std::unordered_map<irep_idt, std::vector<reference_typet>>
2121
generic_parameter_specialization_mapt;
22+
typedef std::set<irep_idt> generic_parameter_recursion_trackingt;
2223

2324
class namespacet;
2425

@@ -35,7 +36,8 @@ class select_pointer_typet
3536
pointer_typet specialize_generics(
3637
const pointer_typet &pointer_type,
3738
const generic_parameter_specialization_mapt
38-
&generic_parameter_specialization_map) const;
39+
&generic_parameter_specialization_map,
40+
generic_parameter_recursion_trackingt &) const;
3941
};
4042

4143
#endif // CPROVER_JAVA_BYTECODE_SELECT_POINTER_TYPE_H

0 commit comments

Comments
 (0)