/** * This (recursive) utility method makes sure that no subroutine is calling a subroutine that uses * the same local variable for the RET as themselves (recursively). This includes that subroutines * may not call themselves recursively, even not through intermediate calls to other subroutines. * * @throws StructuralCodeConstraintException if the above constraint is not satisfied. */ private void noRecursiveCalls(Subroutine sub, HashSet<Integer> set) { Subroutine[] subs = sub.subSubs(); for (int i = 0; i < subs.length; i++) { int index = ((RET) (subs[i].getLeavingRET().getInstruction())).getIndex(); if (!set.add(new Integer(index))) { // Don't use toString() here because of possibly infinite recursive subSubs() calls then. SubroutineImpl si = (SubroutineImpl) subs[i]; throw new StructuralCodeConstraintException( "Subroutine with local variable '" + si.localVariable + "', JSRs '" + si.theJSRs + "', RET '" + si.theRET + "' is called by a subroutine which uses the same local variable index as itself; maybe even a recursive call? JustIce's clean definition of a subroutine forbids both."); } noRecursiveCalls(subs[i], set); set.remove(new Integer(index)); } }