private void fillSpawnTable(MethodTableEntry me) { InstructionList il = me.mg.getInstructionList(); InstructionHandle[] ins = il.getInstructionHandles(); il.setPositions(); int spawnId = 0; for (int k = 0; k < ins.length; k++) { if (ins[k].getInstruction() instanceof INVOKEVIRTUAL) { Method target = self.findMethod((INVOKEVIRTUAL) (ins[k] .getInstruction())); JavaClass cl = self.findMethodClass((INVOKEVIRTUAL) (ins[k] .getInstruction())); if (isSpawnable(target, cl)) { // we have a spawn! analyzeSpawn(me, ins[k], spawnId); spawnId++; } } } }
private int calcNrSpawns(MethodGen mg) { InstructionList il = mg.getInstructionList(); if (il == null) { return 0; } InstructionHandle[] ins = il.getInstructionHandles(); int count = 0; for (int i = 0; i < ins.length; i++) { if (ins[i].getInstruction() instanceof INVOKEVIRTUAL) { Method target = self.findMethod((INVOKEVIRTUAL) (ins[i] .getInstruction())); JavaClass cl = self.findMethodClass((INVOKEVIRTUAL) (ins[i] .getInstruction())); if (isSpawnable(target, cl)) { count++; } } } return count; }
boolean containsSpawnedCall(MethodGen m) { InstructionList code = m.getInstructionList(); if (code == null) { return false; } InstructionHandle ih[] = code.getInstructionHandles(); for (int i = 0; i < ih.length; i++) { Instruction ins = ih[i].getInstruction(); if (ins instanceof INVOKEVIRTUAL) { Method target = self.findMethod((INVOKEVIRTUAL) (ins)); JavaClass cl = self.findMethodClass((INVOKEVIRTUAL) (ins)); if (isSpawnable(target, cl)) { return true; } } } return false; }
private void insertSync(Analyzer analyzer) throws MethodRewriteFailure { d.log(1, "trying to insert sync statement(s)\n"); InstructionHandle[] ihs = analyzer.proposeSyncInsertion(this, new Debug(d.turnedOn(), d.getStartLevel() + 2)); InstructionList instructionList = getInstructionList(); for (InstructionHandle ih : ihs) { InstructionHandle syncInvoke = instructionList.insert(ih, new INVOKEVIRTUAL(indexSync)); InstructionHandle newTarget = instructionList.insert(syncInvoke, spawnableCalls.get(0).getObjectReference().getInstruction()); // the same objectReference for every sync insertion instructionList.redirectBranches(ih, newTarget); d.log(2, "inserted sync()\n"); } d.log(1, "inserted sync statement(s)\n"); }
private boolean callsSync() { ConstantPoolGen cpg = getConstantPool(); InstructionList instructionList = getInstructionList(); InstructionHandle handle = instructionList.getStart(); while (handle != null) { Instruction ins = handle.getInstruction(); if (ins instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL inv = (INVOKEVIRTUAL) ins; if (inv.getMethodName(cpg).equals("sync") && inv.getSignature(cpg).equals("()V")) { JavaClass cl = findMethodClass(inv, cpg); if (cl != null && cl.getClassName().equals("ibis.cashmere.CashmereObject")) { return true; } } } handle = handle.getNext(); } return false; }
public boolean preScreen(MethodGen mg) { ConstantPoolGen cpg = mg.getConstantPool(); int lockCount = mg.isSynchronized() ? 1 : 0; boolean sawWaitOrNotify = false; InstructionHandle handle = mg.getInstructionList().getStart(); while (handle != null && !(lockCount >= 2 && sawWaitOrNotify)) { Instruction ins = handle.getInstruction(); if (ins instanceof MONITORENTER) ++lockCount; else if (ins instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL inv = (INVOKEVIRTUAL) ins; String methodName = inv.getMethodName(cpg); if (methodName.equals("wait") || methodName.startsWith("notify")) sawWaitOrNotify = true; } handle = handle.getNext(); } return lockCount >= 2 && sawWaitOrNotify; }
@Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { if (obj.getMethodName(cpg).equals("cast") && obj.getClassName(cpg).equals("java.lang.Class")) { // treat as no-op try { ValueNumberFrame frame = getFrame(); ValueNumber resultType = frame.popValue(); frame.popValue(); frame.pushValue(resultType); } catch (DataflowAnalysisException e) { AnalysisContext.logError("oops", e); } return; } // Don't know what this method invocation is doing. // Kill all loads. if (obj.getMethodName(cpg).toLowerCase().indexOf("lock") >= 0) getFrame().killAllLoads(); else killLoadsOfObjectsPassed(obj); handleNormalInstruction(obj); }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException{ JavaClass clazz = classContext.getJavaClass(); ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location loc = i.next(); Instruction inst = loc.getHandle().getInstruction(); if (inst instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL)inst; if( "java.lang.StringBuilder".equals(invoke.getClassName(cpg)) && "append".equals(invoke.getMethodName(cpg))) { Instruction prev = loc.getHandle().getPrev().getInstruction(); if (prev instanceof LDC) { LDC ldc = (LDC)prev; Object value = ldc.getValue(cpg); if (value instanceof String) { String v = (String)value; if ("redirect:".equals(v)) { BugInstance bug = new BugInstance(this, SPRING_UNVALIDATED_REDIRECT_TYPE, Priorities.NORMAL_PRIORITY); bug.addClass(clazz).addMethod(clazz,m).addSourceLine(classContext,m,loc); reporter.reportBug(bug); } } } } } } }
/** * This method is used to track calls made on a specific object. For instance, this could be used to track if "setHttpOnly(true)" * was executed on a specific cookie object. * * This allows the detector to find interchanged calls like this * * Cookie cookie1 = new Cookie("f", "foo"); <- This cookie is unsafe * Cookie cookie2 = new Cookie("b", "bar"); <- This cookie is safe * cookie1.setHttpOnly(false); * cookie2.setHttpOnly(true); * * @param cpg ConstantPoolGen * @param startLocation The Location of the cookie initialization call. * @param objectStackLocation The index of the cookie on the stack. * @param invokeInstruction The instruction we want to detect.s * @return The location of the invoke instruction provided for the cookie at a specific index on the stack. */ private Location getCookieInstructionLocation(ConstantPoolGen cpg, Location startLocation, int objectStackLocation, String invokeInstruction) { Location location = startLocation; InstructionHandle handle = location.getHandle(); int loadedStackValue = 0; // Loop until we find the setSecure call for this cookie while (handle.getNext() != null) { handle = handle.getNext(); Instruction nextInst = handle.getInstruction(); // We check if the index of the cookie used for this invoke is the same as the one provided if (nextInst instanceof ALOAD) { ALOAD loadInst = (ALOAD)nextInst; loadedStackValue = loadInst.getIndex(); } if (nextInst instanceof INVOKEVIRTUAL && loadedStackValue == objectStackLocation) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL) nextInst; String methodNameWithSignature = invoke.getClassName(cpg) + "." + invoke.getMethodName(cpg); if (methodNameWithSignature.equals(invokeInstruction)) { Integer val = ByteCode.getConstantInt(handle.getPrev()); if (val != null && val == TRUE_INT_VALUE) { return new Location(handle, location.getBasicBlock()); } } } } return null; }
private Map<String, List<Location>> get_line_location(Method m, ClassContext classContext){ HashMap<String, List<Location>> all_line_location = new HashMap<>(); ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = null; try { cfg = classContext.getCFG(m); } catch (CFGBuilderException e) { e.printStackTrace(); return all_line_location; } for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location loc = i.next(); Instruction inst = loc.getHandle().getInstruction(); if(inst instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL) inst; // if (classname.equals(invoke.getClassName(cpg)) && // methodName.equals(invoke.getMethodName(cpg))) { if(all_line_location.containsKey(invoke.getMethodName(cpg))){ all_line_location.get(invoke.getMethodName(cpg)).add(loc); }else { LinkedList<Location> loc_list = new LinkedList<>(); loc_list.add(loc); all_line_location.put(invoke.getMethodName(cpg), loc_list); } // } } } return all_line_location; }
private ArrayList<SpawnableCall> getSpawnableCalls(ConstantPoolGen constantPoolGen, MethodGen spawnSignatureGen) throws AssumptionFailure { ArrayList<SpawnableCall> spawnableCalls = new ArrayList<SpawnableCall>(); InstructionList il = getInstructionList(); int indexSpawnableCall = constantPoolGen.lookupMethodref(spawnSignatureGen); if (indexSpawnableCall < 0) return spawnableCalls; INVOKEVIRTUAL spawnableInvoke = new INVOKEVIRTUAL(indexSpawnableCall); InstructionHandle ih = il.getStart(); do { Instruction instruction = ih.getInstruction(); if (instruction.equals(spawnableInvoke)) { if (instruction.produceStack(constantPoolGen) > 0) { spawnableCalls.add(getSpawnableCallReturningValue(ih)); } else if (instruction.produceStack(constantPoolGen) == 0) { if (spawnSignatureGen.getExceptions().length > 0) { spawnableCalls.add(getSpawnableCallWithException(ih, spawnSignatureGen)); } else { throw new AssumptionFailure("Not satisfying assumption that spawnable method returns something or throws something"); } } else { throw new AssumptionFailure("Not satisfying assumption that spawnable method returns something or throws something"); } } else { // OK } } while((ih = ih.getNext()) != null); return spawnableCalls; }
public boolean isStreamClose(BasicBlock basicBlock, InstructionHandle handle, ConstantPoolGen cpg, ResourceValueFrame frame, RepositoryLookupFailureCallback lookupFailureCallback) { if (!mightCloseStream(basicBlock, handle, cpg)) return false; Instruction ins = handle.getInstruction(); if ((ins instanceof INVOKEVIRTUAL) || (ins instanceof INVOKEINTERFACE)) { // Does this instruction close the stream? InvokeInstruction inv = (InvokeInstruction) ins; if (!frame.isValid() || !getInstanceValue(frame, inv, cpg).isInstance()) return false; // It's a close if the invoked class is any subtype of the stream // base class. // (Basically, we may not see the exact original stream class, // even though it's the same instance.) try { String classClosed = inv.getClassName(cpg); return Hierarchy.isSubtype(classClosed, streamBase) || Hierarchy.isSubtype(streamBase, classClosed) ; } catch (ClassNotFoundException e) { lookupFailureCallback.reportMissingClass(e); return false; } } return false; }
@Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { if (returnsString(obj)) handleInstanceMethod(obj); else super.visitINVOKEVIRTUAL(obj); }
private boolean isStringAppend(Instruction ins, ConstantPoolGen cpg) { if (ins instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL) ins; if (invoke.getMethodName(cpg).equals("append") && invoke.getClassName(cpg).startsWith("java.lang.StringB")) { String sig = invoke.getSignature(cpg); char firstChar = sig.charAt(1); return firstChar == '[' || firstChar == 'L'; } } return false; }
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o){ try { // INVOKEVIRTUAL is a LoadClass; the Class where the referenced method is declared in, // is therefore resolved/verified. // INVOKEVIRTUAL is an InvokeInstruction, the argument and return types are resolved/verified, // too. So are the allowed method names. String classname = o.getClassName(cpg); JavaClass jc = Repository.lookupClass(classname); Method[] ms = jc.getMethods(); Method m = null; for (int i=0; i<ms.length; i++){ if ( (ms[i].getName().equals(o.getMethodName(cpg))) && (Type.getReturnType(ms[i].getSignature()).equals(o.getReturnType(cpg))) && (objarrayequals(Type.getArgumentTypes(ms[i].getSignature()), o.getArgumentTypes(cpg))) ){ m = ms[i]; break; } } if (m == null){ constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature '"+o.getSignature(cpg)+"' not found in class '"+jc.getClassName()+"'. The native verifier does allow the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not."); } if (! (jc.isClass())){ constraintViolated(o, "Referenced class '"+jc.getClassName()+"' is an interface, but not a class as expected."); } } catch (ClassNotFoundException e) { // FIXME: maybe not the best way to handle this throw new AssertionViolatedException("Missing class: " + e.toString()); } }
/** @see org.apache.bcel.generic.Visitor */ public void visitINVOKEVIRTUAL(INVOKEVIRTUAL aINVOKEVIRTUAL) { addInvokeReference( new InvokeReference(aINVOKEVIRTUAL, mCurrentPoolGen)); }
@Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { visitInvoke(obj); }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException { HashMap<Location, String> sslConnMap = new HashMap<Location, String>(); HashSet<String> sslCertVerSet = new HashSet<String>(); Location locationWeakness = null; String hostName = null; ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); if (inst instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL) inst; if (INSECURE_APIS.contains(invoke.getClassName(cpg)) && "setHostName".equals(invoke.getMethodName(cpg))) { hostName = ByteCode.getConstantLDC(location.getHandle().getPrev(), cpg, String.class); } if (INSECURE_APIS.contains(invoke.getClassName(cpg)) && "setSSLOnConnect".equals(invoke.getMethodName(cpg))) { Integer sslOn = ByteCode.getConstantInt(location.getHandle().getPrev()); if (sslOn != null && sslOn == 1) { sslConnMap.put(location, invoke.getClassName(cpg)+hostName); } } if (INSECURE_APIS.contains(invoke.getClassName(cpg)) && "setSSLCheckServerIdentity".equals(invoke.getMethodName(cpg))) { Integer checkOn = ByteCode.getConstantInt(location.getHandle().getPrev()); if (checkOn != null && checkOn == 1) { sslCertVerSet.add(invoke.getClassName(cpg)+hostName); } } } } //Both conditions - setSSLOnConnect and setSSLCheckServerIdentity //haven't been found in the same instance (verifing instance by class name + host name) sslConnMap.values().removeAll(sslCertVerSet); if (!sslConnMap.isEmpty()) { for (Location key : sslConnMap.keySet()) { JavaClass clz = classContext.getJavaClass(); bugReporter.reportBug(new BugInstance(this, INSECURE_SMTP_SSL, Priorities.HIGH_PRIORITY) .addClass(clz) .addMethod(clz, m) .addSourceLine(classContext, m, key)); } } }
void generateMain(ClassGen clg, Method origMain) { InstructionList il = new InstructionList(); MethodGen new_main = new MethodGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC, Type.VOID, new Type[] { new ArrayType( Type.STRING, 1) }, new String[] { "argv" }, "main", clg .getClassName(), il, clg.getConstantPool()); il.append(ins_f.createNew(cashmereType)); il.append(new DUP()); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "isMaster", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); BranchHandle ifcmp = il.append(new IFEQ(null)); InstructionHandle origMain_handle = il.append(new ALOAD(0)); InstructionHandle try_start = il.append(ins_f.createInvoke(clg .getClassName(), origMain.getName(), Type.VOID, new Type[] { new ArrayType(Type.STRING, 1) }, Constants.INVOKESTATIC)); BranchHandle try_end = il.append(new GOTO(null)); InstructionHandle e_handler = il.append(getCashmere(ins_f)); il.append(new SWAP()); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "exit", Type.VOID, new Type[] { new ObjectType("java.lang.Throwable")}, Constants.INVOKEVIRTUAL)); BranchHandle gto2 = il.append(new GOTO(null)); InstructionHandle ifeq_target = il.append(getCashmere(ins_f)); ifcmp.setTarget(ifeq_target); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "client", Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(getCashmere(ins_f)); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "isMaster", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(new IFNE(origMain_handle)); InstructionHandle gto_target = il.append(getCashmere(ins_f)); try_end.setTarget(gto_target); il.append(ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "exit", Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); InstructionHandle gto2_target = il.append(new RETURN()); gto2.setTarget(gto2_target); new_main.addExceptionHandler(try_start, try_end, e_handler, new ObjectType("java.lang.Throwable")); new_main.setMaxStack(); new_main.setMaxLocals(); new_main.addLocalVariable("argv", new ArrayType(Type.STRING, 1), 0, origMain_handle, null); removeLocalTypeTables(new_main); Method main = new_main.getMethod(); gen_c.addMethod(main); }
void rewriteAbort(MethodGen m, InstructionList il, InstructionHandle i, int maxLocals) { // in a clone, we have to abort two lists: the outstanding spawns of // the parent, and the outstanding spawns of the clone. Instruction fa = getCashmere(ins_f); Instruction ab = ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "abort", Type.VOID, new Type[] { irType, irType }, Constants.INVOKEVIRTUAL); if (mtab.isClone(m)) { int parentPos = 3; if (!m.isStatic()) { // we have an additional 'this' param parentPos++; } i.getPrev().getPrev().setInstruction(fa); // push outstanding spawns i.getPrev().setInstruction(new ALOAD(maxLocals - 3)); // push parent invocationrecord i.setInstruction(new ALOAD(parentPos)); i = i.getNext(); } else if (mtab.containsInlet(m)) { i.getPrev().getPrev().setInstruction(fa); // push outstanding spawns i.getPrev().setInstruction(new ALOAD(maxLocals - 3)); i.setInstruction(new ACONST_NULL()); i = i.getNext(); } else { i.getPrev().setInstruction(fa); // push outstanding spawns i.setInstruction(new ALOAD(maxLocals - 3)); i = i.getNext(); il.insert(i, new ACONST_NULL()); } // and call Cashmere.abort il.insert(i, ab); // all jobs were killed, set outstandingSpawns to null il.insert(i, new ACONST_NULL()); // push null il.insert(i, new ASTORE(maxLocals - 3)); // write }
void insertAbortedCheck(MethodGen m, InstructionList il, InstructionHandle pos) { // Generates: // if (cashmere.getParent() != null && cashmere.getParent().aborted) { // throw new ibis.cashmere.impl.aborts.AbortException(); // } InstructionHandle abo = insertThrowAbort(m, il, pos); il.insert(abo, getCashmere(ins_f)); il.insert(abo, ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "getParent", irType, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); // test for null (root job) il.insert(abo, new IFNULL(pos)); il.insert(abo, getCashmere(ins_f)); il.insert(abo, ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "getParent", irType, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.insert(abo, ins_f.createFieldAccess( "ibis.cashmere.impl.spawnSync.InvocationRecord", "aborted", Type.BOOLEAN, Constants.GETFIELD)); il.insert(abo, new IFEQ(pos)); /* ////@@@@@@@@@@2 this needs fixing :-( // Test for parent.eek, if non-null, throw it (exception in inlet). il.insert(abo, getCashmere(ins_f)); il.insert(abo, ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "getParent", irType, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.insert(abo, ins_f.createFieldAccess( "ibis.cashmere.impl.spawnSync.InvocationRecord", "eek", new ObjectType("java.lang.Throwable"), Constants.GETFIELD)); il.insert(abo, new IFNULL(abo)); il.insert(abo, getCashmere(ins_f)); il.insert(abo, ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "getParent", irType, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.insert(abo, ins_f.createFieldAccess( "ibis.cashmere.impl.spawnSync.InvocationRecord", "eek", new ObjectType("java.lang.Throwable"), Constants.GETFIELD)); il.insert(abo, new ATHROW()); */ }
public static boolean mightCloseStream(BasicBlock basicBlock, InstructionHandle handle, ConstantPoolGen cpg) { Instruction ins = handle.getInstruction(); if ((ins instanceof INVOKEVIRTUAL) || (ins instanceof INVOKEINTERFACE)) { // Does this instruction close the stream? InvokeInstruction inv = (InvokeInstruction) ins; // It's a close if the invoked class is any subtype of the stream // base class. // (Basically, we may not see the exact original stream class, // even though it's the same instance.) return inv.getName(cpg).equals("close") && inv.getSignature(cpg).equals("()V"); } return false; }
private void analyzeMethod(ClassContext classContext, Method method) throws CFGBuilderException, DataflowAnalysisException { MethodGen methodGen = classContext.getMethodGen(method); if (methodGen == null) return; ConstantPoolGen cpg = methodGen.getConstantPool(); CFG cfg = classContext.getCFG(method); ValueNumberDataflow vnaDataflow = classContext.getValueNumberDataflow(method); LockDataflow dataflow = classContext.getLockDataflow(method); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); InstructionHandle handle = location.getHandle(); Instruction ins = handle.getInstruction(); if (!(ins instanceof INVOKEVIRTUAL)) continue; INVOKEVIRTUAL inv = (INVOKEVIRTUAL) ins; String methodName = inv.getName(cpg); String methodSig = inv.getSignature(cpg); if (Hierarchy.isMonitorWait(methodName, methodSig) || Hierarchy.isMonitorNotify(methodName, methodSig)) { int numConsumed = inv.consumeStack(cpg); if (numConsumed == Constants.UNPREDICTABLE) throw new DataflowAnalysisException("Unpredictable stack consumption", methodGen, handle); ValueNumberFrame frame = vnaDataflow.getFactAtLocation(location); if (!frame.isValid()) // Probably dead code continue; if (frame.getStackDepth() - numConsumed < 0) throw new DataflowAnalysisException("Stack underflow", methodGen, handle); ValueNumber ref = frame.getValue(frame.getNumSlots() - numConsumed); LockSet lockSet = dataflow.getFactAtLocation(location); int lockCount = lockSet.getLockCount(ref.getNumber()); if (lockCount == 0) { Collection<ValueNumber> lockedValueNumbers = lockSet.getLockedValueNumbers(frame); boolean foundMatch = false; for (ValueNumber v : lockedValueNumbers) if (frame.veryFuzzyMatch(ref, v)) { foundMatch = true; break; } if (!foundMatch) { String type = methodName.equals("wait") ? "MWN_MISMATCHED_WAIT" : "MWN_MISMATCHED_NOTIFY"; String sourceFile = classContext.getJavaClass().getSourceFileName(); // Report as medium priority only if the method is // public. // Non-public methods may be properly locked in a // calling context. int priority = method.isPublic() ? NORMAL_PRIORITY : LOW_PRIORITY; bugAccumulator.accumulateBug( new BugInstance(this, type, priority).addClassAndMethod(methodGen, sourceFile), SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle)); } } } } bugAccumulator.reportAccumulatedBugs(); }
@Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL inv) { handleInvoke(inv); }
@Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { handleInvoke(obj); }
@Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL invoke) { addMethodCall(method, invoke, constantPoolGen); }