@@ -33,7 +33,7 @@ pointer_typet select_pointer_typet::convert_pointer_type(
3333 if (!generic_parameter_specialization_map.empty ())
3434 {
3535 generic_parameter_recursion_trackingt visited;
36- auto type = specialize_generics (
36+ const auto & type = specialize_generics (
3737 pointer_type, generic_parameter_specialization_map, visited);
3838 INVARIANT (visited.empty (), " recursion stack must be empty here" );
3939 return type;
@@ -84,8 +84,7 @@ pointer_typet select_pointer_typet::specialize_generics(
8484 const pointer_typet &type =
8585 generic_parameter_specialization_map.find (parameter_name)->second .back ();
8686
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
8988 if (visited_nodes.find (parameter_name) != visited_nodes.end ())
9089 {
9190 optionalt<pointer_typet> result = get_instantiated_type (
@@ -103,20 +102,16 @@ pointer_typet select_pointer_typet::specialize_generics(
103102
104103 // generic parameters can be adopted from outer classes or superclasses so
105104 // 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))
118106 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;
120115 }
121116 else if (pointer_type.subtype ().id () == ID_symbol)
122117 {
@@ -165,13 +160,10 @@ optionalt<pointer_typet> select_pointer_typet::get_instantiated_type(
165160 current_parameter, generic_parameter_specialization_map, visited, depth);
166161 if (retval.has_value ())
167162 {
168- if (is_java_generic_parameter (*retval))
169- {
170- UNREACHABLE;
171- }
163+ CHECK_RETURN (!is_java_generic_parameter (*retval));
172164 return retval;
173165 }
174- INVARIANT (visited.empty (), " recursion set must be empty here " );
166+ CHECK_RETURN (visited.empty ());
175167
176168 const auto &entry =
177169 generic_parameter_specialization_map.find (current_parameter)
@@ -184,9 +176,11 @@ optionalt<pointer_typet> select_pointer_typet::get_instantiated_type(
184176 return {};
185177}
186178
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.
189182// / \param visited tracks the visited parameter names
183+ // / \param depth stack depth to analyze
190184optionalt<pointer_typet> select_pointer_typet::get_instantiated_type (
191185 const irep_idt ¶meter_name,
192186 const generic_parameter_specialization_mapt
@@ -195,55 +189,41 @@ optionalt<pointer_typet> select_pointer_typet::get_instantiated_type(
195189 const size_t depth) const
196190{
197191 // 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
199193 // 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
203195
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" );
210200
211- INVARIANT (
212- depth < replacements.size (), " cannot access elements outside stack" );
201+ const auto &replacements = val->second ;
213202
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 {};
243210 }
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))
246216 {
247- UNREACHABLE ;
217+ return type ;
248218 }
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;
249229}
0 commit comments