@@ -420,6 +420,39 @@ static void create_stub_global_symbol(
420420 !add_failed, " caller should have checked symbol not already in table" );
421421}
422422
423+ // / Find any incomplete ancestor of a given class
424+ // / \param start_class_id: class to start searching from
425+ // / \param symbol_table: global symbol table
426+ // / \param class_hierarchy: global class hierarchy
427+ // / \return first incomplete ancestor encountered,
428+ // / including start_class_id itself.
429+ static irep_idt get_any_incomplete_ancestor (
430+ const irep_idt &start_class_id,
431+ const symbol_tablet &symbol_table,
432+ const class_hierarchyt &class_hierarchy)
433+ {
434+ // Depth-first search: return the first ancestor with ID_incomplete_class, or
435+ // irep_idt() if none found.
436+ std::vector<irep_idt> classes_to_check;
437+ classes_to_check.push_back (start_class_id);
438+
439+ while (!classes_to_check.empty ())
440+ {
441+ irep_idt to_check = classes_to_check.back ();
442+ classes_to_check.pop_back ();
443+
444+ if (symbol_table.lookup_ref (to_check).type .get_bool (ID_incomplete_class))
445+ return to_check;
446+
447+ const class_hierarchyt::idst &parents =
448+ class_hierarchy.class_map .at (to_check).parents ;
449+ classes_to_check.insert (
450+ classes_to_check.end (), parents.begin (), parents.end ());
451+ }
452+
453+ INVARIANT (false , " input class id should have some incomplete ancestor" );
454+ }
455+
423456// / Search for getstatic and putstatic instructions in a class' bytecode and
424457// / create stub symbols for any static fields that aren't already in the symbol
425458// / table. The new symbols are null-initialised for reference-typed globals /
@@ -463,19 +496,12 @@ static void create_stub_global_symbols(
463496 true );
464497 if (!referred_component.is_valid ())
465498 {
466- // Create a new stub global on the first incomplete (stub) parent of
467- // the class that was referred to:
468- irep_idt add_to_class_id = class_id;
469- while (!symbol_table.lookup_ref (add_to_class_id).type .get_bool (
470- ID_incomplete_class))
471- {
472- const class_hierarchyt::idst &parents =
473- class_hierarchy.class_map .at (add_to_class_id).parents ;
474- INVARIANT (
475- !parents.empty (),
476- " unresolved global reference should come from incomplete class" );
477- add_to_class_id = parents[0 ];
478- }
499+ // Create a new stub global on an arbitrary incomplete ancestor of the
500+ // class that was referred to. This is just a guess, but we have no
501+ // better information to go on.
502+ irep_idt add_to_class_id =
503+ get_any_incomplete_ancestor (
504+ class_id, symbol_table, class_hierarchy);
479505
480506 irep_idt identifier =
481507 id2string (add_to_class_id) + " ." + id2string (component);
0 commit comments