/** * Clone non-static ancestor methods that are not hidden by virtual dispatch and that are * reachable based on a pta run. */ private void cloneReachableNonHiddenAncestorMethods(SootClass ancestor) { if (ClassCloner.isClonedClass(ancestor)) { logger.error("Cloning method from clone: {}", ancestor); droidsafe.main.Main.exit(1); } // create all methods, cloning body, replacing instance field refs for (SootMethod ancestorM : ancestor.getMethods()) { if (ancestorM.isAbstract() || ancestorM.isPhantom() || !ancestorM.isConcrete() || SootUtils.isRuntimeStubMethod(ancestorM)) continue; // never clone static methods if (ancestorM.isStatic()) continue; // clone only reachable methods if (!cloneAllMethods && !PTABridge.v().getReachableMethods().contains(ancestorM)) continue; // check if this method already exists if (containsMethod(ancestorM.getSignature())) { // System.out.printf("\tAlready contains method %s.\n", ancestorM); continue; } // turn off final for ancestor methods if (ancestorM.isFinal()) ancestorM.setModifiers(ancestorM.getModifiers() ^ Modifier.FINAL); cloneMethod(ancestorM, ancestorM.getName()); } }