@@ -33,7 +33,7 @@ pointer_typet select_pointer_typet::convert_pointer_type(
33
33
if (!generic_parameter_specialization_map.empty ())
34
34
{
35
35
generic_parameter_recursion_trackingt visited;
36
- auto type = specialize_generics (
36
+ const auto & type = specialize_generics (
37
37
pointer_type, generic_parameter_specialization_map, visited);
38
38
INVARIANT (visited.empty (), " recursion stack must be empty here" );
39
39
return type;
@@ -84,8 +84,7 @@ pointer_typet select_pointer_typet::specialize_generics(
84
84
const pointer_typet &type =
85
85
generic_parameter_specialization_map.find (parameter_name)->second .back ();
86
86
87
- // if we have already seen this before, we will not learn any additional
88
- // information from further recursion, only cause a segmentation fault.
87
+ // avoid infinite recursion
89
88
if (visited_nodes.find (parameter_name) != visited_nodes.end ())
90
89
{
91
90
optionalt<pointer_typet> result = get_instantiated_type (
@@ -103,20 +102,16 @@ pointer_typet select_pointer_typet::specialize_generics(
103
102
104
103
// generic parameters can be adopted from outer classes or superclasses so
105
104
// we may need to search for the concrete type recursively
106
- if (is_java_generic_parameter (type))
107
- {
108
- visited_nodes.insert (parameter_name);
109
- auto returned_type = specialize_generics (
110
- to_java_generic_parameter (type),
111
- generic_parameter_specialization_map,
112
- visited_nodes);
113
- visited_nodes.erase (parameter_name);
114
- return returned_type;
115
- }
116
- else
117
- {
105
+ if (!is_java_generic_parameter (type))
118
106
return type;
119
- }
107
+
108
+ visited_nodes.insert (parameter_name);
109
+ auto returned_type = specialize_generics (
110
+ to_java_generic_parameter (type),
111
+ generic_parameter_specialization_map,
112
+ visited_nodes);
113
+ visited_nodes.erase (parameter_name);
114
+ return returned_type;
120
115
}
121
116
else if (pointer_type.subtype ().id () == ID_symbol)
122
117
{
@@ -165,13 +160,10 @@ optionalt<pointer_typet> select_pointer_typet::get_instantiated_type(
165
160
current_parameter, generic_parameter_specialization_map, visited, depth);
166
161
if (retval.has_value ())
167
162
{
168
- if (is_java_generic_parameter (*retval))
169
- {
170
- UNREACHABLE;
171
- }
163
+ CHECK_RETURN (!is_java_generic_parameter (*retval));
172
164
return retval;
173
165
}
174
- INVARIANT (visited.empty (), " recursion set must be empty here " );
166
+ CHECK_RETURN (visited.empty ());
175
167
176
168
const auto &entry =
177
169
generic_parameter_specialization_map.find (current_parameter)
@@ -184,9 +176,11 @@ optionalt<pointer_typet> select_pointer_typet::get_instantiated_type(
184
176
return {};
185
177
}
186
178
187
- // / See above, the additional parameter just tracks the recursion to prevent
188
- // / visiting the same depth again.
179
+ // / See get_instantiated_type, the additional parameters just track the
180
+ // / recursion to prevent, visiting the same depth again and specify which stack
181
+ // / depth is analyzed.
189
182
// / \param visited tracks the visited parameter names
183
+ // / \param depth stack depth to analyze
190
184
optionalt<pointer_typet> select_pointer_typet::get_instantiated_type (
191
185
const irep_idt ¶meter_name,
192
186
const generic_parameter_specialization_mapt
@@ -195,55 +189,41 @@ optionalt<pointer_typet> select_pointer_typet::get_instantiated_type(
195
189
const size_t depth) const
196
190
{
197
191
// Get the pointed to instantiation type at the desired stack depth.
198
- // - f this type is not a generic type, it is returned as a valid
192
+ // - if this type is not a generic type, it is returned as a valid
199
193
// instantiation
200
- // - if another recursion at this depth level is found, the search depth is
201
- // increased
202
- // - if nothing can be found an empty optional is returned
194
+ // - if nothing can be found at the given depth, an empty optional is returned
203
195
204
- if (
205
- generic_parameter_specialization_map.find (parameter_name) !=
206
- generic_parameter_specialization_map.end ())
207
- {
208
- const auto &replacements =
209
- generic_parameter_specialization_map.find (parameter_name)->second ;
196
+ auto val = generic_parameter_specialization_map.find (parameter_name);
197
+ INVARIANT (
198
+ val != generic_parameter_specialization_map.end (),
199
+ " generic parameter must be a key in map" );
210
200
211
- INVARIANT (
212
- depth < replacements.size (), " cannot access elements outside stack" );
201
+ const auto &replacements = val->second ;
213
202
214
- // Check if there is a recursion loop, if yes return with nothing found
215
- if (visited.find (parameter_name) != visited.end ())
216
- {
217
- return {};
218
- }
219
- else
220
- {
221
- const size_t index = (replacements.size () - depth) - 1 ;
222
- const auto &type = replacements[index ];
223
- {
224
- if (!is_java_generic_parameter (type))
225
- {
226
- return type;
227
- }
228
- else
229
- {
230
- visited.insert (parameter_name);
231
- const auto &gen_type =
232
- to_java_generic_parameter (type).type_variable ();
233
- const auto val = get_instantiated_type (
234
- gen_type.get_identifier (),
235
- generic_parameter_specialization_map,
236
- visited,
237
- depth);
238
- visited.erase (parameter_name);
239
- return val;
240
- }
241
- }
242
- }
203
+ INVARIANT (
204
+ depth < replacements.size (), " cannot access elements outside stack" );
205
+
206
+ // Check if there is a recursion loop, if yes return with nothing found
207
+ if (visited.find (parameter_name) != visited.end ())
208
+ {
209
+ return {};
243
210
}
244
- // parameter_name not found in map
245
- else
211
+
212
+ const size_t index = (replacements.size () - depth) - 1 ;
213
+ const auto &type = replacements[index ];
214
+
215
+ if (!is_java_generic_parameter (type))
246
216
{
247
- UNREACHABLE ;
217
+ return type ;
248
218
}
219
+
220
+ visited.insert (parameter_name);
221
+ const auto &gen_type = to_java_generic_parameter (type).type_variable ();
222
+ const auto inst_val = get_instantiated_type (
223
+ gen_type.get_identifier (),
224
+ generic_parameter_specialization_map,
225
+ visited,
226
+ depth);
227
+ visited.erase (parameter_name);
228
+ return inst_val;
249
229
}
0 commit comments