@@ -73,6 +73,16 @@ pointer_typet select_pointer_typet::specialize_generics(
73
73
const java_generic_parametert ¶meter =
74
74
to_java_generic_parameter (pointer_type);
75
75
const irep_idt ¶meter_name = parameter.get_name ();
76
+
77
+ // avoid infinite recursion by looking at each generic argument from
78
+ // previous assignments
79
+ if (visited_nodes.find (parameter_name) != visited_nodes.end ())
80
+ {
81
+ const optionalt<pointer_typet> result = get_recursively_instantiated_type (
82
+ parameter_name, generic_parameter_specialization_map);
83
+ return result.has_value () ? result.value () : pointer_type;
84
+ }
85
+
76
86
if (generic_parameter_specialization_map.count (parameter_name) == 0 )
77
87
{
78
88
// this means that the generic pointer_type has not been specialized
@@ -84,21 +94,13 @@ pointer_typet select_pointer_typet::specialize_generics(
84
94
const pointer_typet &type =
85
95
generic_parameter_specialization_map.find (parameter_name)->second .back ();
86
96
87
- // avoid infinite recursion
88
- if (visited_nodes.find (parameter_name) != visited_nodes.end ())
89
- {
90
- optionalt<pointer_typet> result = get_recursively_instantiated_type (
91
- parameter_name, generic_parameter_specialization_map);
92
- return result.has_value () ? result.value () : pointer_type;
93
- }
94
-
95
97
// generic parameters can be adopted from outer classes or superclasses so
96
98
// we may need to search for the concrete type recursively
97
99
if (!is_java_generic_parameter (type))
98
100
return type;
99
101
100
102
visited_nodes.insert (parameter_name);
101
- auto returned_type = specialize_generics (
103
+ const auto returned_type = specialize_generics (
102
104
to_java_generic_parameter (type),
103
105
generic_parameter_specialization_map,
104
106
visited_nodes);
@@ -135,20 +137,19 @@ pointer_typet select_pointer_typet::specialize_generics(
135
137
// / instantiated
136
138
// / \param generic_specialization_map Map of type names to specialization stack
137
139
// / \return The first instantiated type for the generic type or nothing if no
138
- // / such instantiation exists.
140
+ // / such instantiation exists.
139
141
optionalt<pointer_typet>
140
142
select_pointer_typet::get_recursively_instantiated_type (
141
143
const irep_idt ¶meter_name,
142
144
const generic_parameter_specialization_mapt
143
145
&generic_parameter_specialization_map) const
144
146
{
145
147
generic_parameter_recursion_trackingt visited;
146
- size_t depth = 0 ;
147
- const size_t max =
148
+ const size_t max_depth =
148
149
generic_parameter_specialization_map.find (parameter_name)->second .size ();
149
150
150
151
irep_idt current_parameter = parameter_name;
151
- while ( depth < max )
152
+ for ( size_t depth = 0 ; depth < max_depth; depth++ )
152
153
{
153
154
const auto retval = get_recursively_instantiated_type (
154
155
current_parameter, generic_parameter_specialization_map, visited, depth);
@@ -162,19 +163,19 @@ select_pointer_typet::get_recursively_instantiated_type(
162
163
const auto &entry =
163
164
generic_parameter_specialization_map.find (current_parameter)
164
165
->second .back ();
165
- const java_generic_parametert &gen_param = to_java_generic_parameter (entry);
166
- const auto &type_var = gen_param.type_variable ();
167
- current_parameter = type_var.get_identifier ();
168
- depth++;
166
+ current_parameter = to_java_generic_parameter (entry).get_name ();
169
167
}
170
168
return {};
171
169
}
172
170
173
171
// / See get_recursively instantiated_type, the additional parameters just track
174
- // / the recursion to prevent, visiting the same depth again and specify which
172
+ // / the recursion to prevent visiting the same depth again and specify which
175
173
// / stack depth is analyzed.
176
174
// / \param visited Tracks the visited parameter names
177
175
// / \param depth Stack depth to analyze
176
+ // / \return if this type is not a generic type, it is returned as a valid
177
+ // / instantiation, if nothing can be found at the given depth, en empty optional
178
+ // / is returned
178
179
optionalt<pointer_typet>
179
180
select_pointer_typet::get_recursively_instantiated_type (
180
181
const irep_idt ¶meter_name,
@@ -183,12 +184,7 @@ select_pointer_typet::get_recursively_instantiated_type(
183
184
generic_parameter_recursion_trackingt &visited,
184
185
const size_t depth) const
185
186
{
186
- // Get the pointed to instantiation type at the desired stack depth.
187
- // - if this type is not a generic type, it is returned as a valid
188
- // instantiation
189
- // - if nothing can be found at the given depth, an empty optional is returned
190
-
191
- auto val = generic_parameter_specialization_map.find (parameter_name);
187
+ const auto &val = generic_parameter_specialization_map.find (parameter_name);
192
188
INVARIANT (
193
189
val != generic_parameter_specialization_map.end (),
194
190
" generic parameter must be a key in map" );
@@ -204,7 +200,7 @@ select_pointer_typet::get_recursively_instantiated_type(
204
200
return {};
205
201
}
206
202
207
- const size_t index = (replacements.size () - depth ) - 1 ;
203
+ const size_t index = (replacements.size () - 1 ) - depth ;
208
204
const auto &type = replacements[index];
209
205
210
206
if (!is_java_generic_parameter (type))
@@ -213,9 +209,8 @@ select_pointer_typet::get_recursively_instantiated_type(
213
209
}
214
210
215
211
visited.insert (parameter_name);
216
- const auto &gen_type = to_java_generic_parameter (type).type_variable ();
217
212
const auto inst_val = get_recursively_instantiated_type (
218
- gen_type. get_identifier (),
213
+ to_java_generic_parameter (type). get_name (),
219
214
generic_parameter_specialization_map,
220
215
visited,
221
216
depth);
0 commit comments