public SourceLineAnnotation getSourceLineAnnotation() { return SourceLineAnnotation.fromVisitedInstruction(method.getMethodDescriptor(), pc); }
public BugInstance addClassAndMethod(XMethod xMethod) { return addClassAndMethod(xMethod.getMethodDescriptor()); }
public void analysisSkippedDueToInvokeDynamic(XMethod m) { if (!m.usesInvokeDynamic()) { throw new IllegalArgumentException(); } if (skippedDueToInvokeDynamic.add(m.getMethodDescriptor())) { logAnError(m + " skipped due to invoke_dynamic"); } }
@Override public void addVertex(InterproceduralCallGraphVertex v) { super.addVertex(v); methodDescToVertexMap.put(v.getXmethod().getMethodDescriptor(), v); }
private void check(XMethod xmethod, ClassDescriptor annotation, boolean expectWarnings, int priority) { AnnotationValue expect = xmethod.getAnnotation(annotation); if (expect == null) { return; } if (DEBUG) { System.out.println("*** Found " + annotation + " annotation on " + xmethod); } FieldOrMethodDescriptor descriptor = xmethod.getMethodDescriptor(); Collection<BugInstance> warnings = warningsByMethod.get(descriptor); check(expect, descriptor, warnings, expectWarnings, priority, descriptor.getClassDescriptor()); }
private static void getDirectlyRelevantTypeQualifiers(XMethod xmethod, HashSet<TypeQualifierValue<?>> result) { result.addAll(AnalysisContext.currentAnalysisContext().getDirectlyRelevantTypeQualifiersDatabase() .getDirectlyRelevantTypeQualifiers(xmethod.getMethodDescriptor())); }
/** * @param item stack item to check * @return true if this stack item is known to be newly created */ private static boolean isNew(OpcodeStack.Item item) { if(item.isNewlyAllocated()) { return true; } XMethod returnValueOf = item.getReturnValueOf(); if(returnValueOf == null) { return false; } if("iterator".equals(returnValueOf.getName()) && "()Ljava/util/Iterator;".equals(returnValueOf.getSignature()) && Subtypes2.instanceOf(returnValueOf.getClassName(), "java.lang.Iterable")) { return true; } if(returnValueOf.getClassName().startsWith("[") && returnValueOf.getName().equals("clone")) { return true; } if(NEW_OBJECT_RETURNING_METHODS.contains(returnValueOf.getMethodDescriptor())) { return true; } return false; }
private static void findSuperMethods(@CheckForNull ClassDescriptor c, XMethod m, Set<XMethod> accumulator) { if (c == null) { return; } try { XClass xc = getXClass(c); XMethod xm = xc.findMatchingMethod(m.getMethodDescriptor()); if (xm != null && !accumulator.add(xm)) { return; } findSuperMethods(xc.getSuperclassDescriptor(), m, accumulator); for (ClassDescriptor i : xc.getInterfaceDescriptorList()) { findSuperMethods(i, m, accumulator); } if (!accumulator.add(m)) { return; } } catch (CheckedAnalysisException e) { AnalysisContext.logError("Error finding super methods for " + m, e); } }
public static @CheckForNull XMethod findFirstSuperMethod(XMethod m) { try { @CheckForNull ClassDescriptor c = m.getClassDescriptor(); XClass xc = getXClass(c); c = xc.getSuperclassDescriptor(); while (c != null) { xc = getXClass(c); XMethod xm = xc.findMatchingMethod(m.getMethodDescriptor()); if (xm != null) { return xm; } c = xc.getSuperclassDescriptor(); } } catch (CheckedAnalysisException e) { AnalysisContext.logError("Error finding super methods for " + m, e); } return null; }
/** * Find the InterproceduralCallGraphVertex for given XMethod. * * @param xmethod * an XMethod * @return the XMethod's InterproceduralCallGraphVertex */ private InterproceduralCallGraphVertex findVertex(XMethod xmethod) { InterproceduralCallGraphVertex vertex; vertex = callGraph.lookupVertex(xmethod.getMethodDescriptor()); if (vertex == null) { vertex = new InterproceduralCallGraphVertex(); vertex.setXmethod(xmethod); callGraph.addVertex(vertex); } return vertex; }
try { XClass xClass = subtype.getXClass(); XMethod subMethod = xClass.findMatchingMethod(xMethod.getMethodDescriptor()); if (subMethod != null) { if(!subMethod.isAbstract() ) {
continue; MethodDescriptor methodDescriptor = xMethod.getMethodDescriptor();
public IsNullValue getReturnValueNullness(XMethod calledMethod) { IsNullValue pushValue; if (IsNullValueAnalysis.DEBUG) { System.out.println("Check " + calledMethod + " for null return..."); } NullnessAnnotation annotation = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase() .getResolvedAnnotation(calledMethod, false); Boolean alwaysNonNull = AnalysisContext.currentAnalysisContext().getReturnValueNullnessPropertyDatabase() .getProperty(calledMethod.getMethodDescriptor()); if (annotation == NullnessAnnotation.CHECK_FOR_NULL) { if (IsNullValueAnalysis.DEBUG) { System.out.println("Null value returned from " + calledMethod); } pushValue = IsNullValue.nullOnSimplePathValue().markInformationAsComingFromReturnValueOfMethod( calledMethod); } else if (annotation == NullnessAnnotation.NULLABLE) { pushValue = IsNullValue.nonReportingNotNullValue(); } else if (annotation == NullnessAnnotation.NONNULL || (alwaysNonNull != null && alwaysNonNull.booleanValue())) { // Method is declared NOT to return null if (IsNullValueAnalysis.DEBUG) { System.out.println("NonNull value return from " + calledMethod); } pushValue = IsNullValue.nonNullValue().markInformationAsComingFromReturnValueOfMethod(calledMethod); } else { pushValue = IsNullValue.nonReportingNotNullValue(); } return pushValue; }
@Override public void sawOpcode(int seen) { if (seen == Const.INVOKESPECIAL) { XMethod m = getXMethodOperand(); if (m == null) { return; } XClass c = getXClass(); int nameDistance = EditDistance.editDistance(m.getName(), getMethodName()); if (nameDistance < 4 && c.findMatchingMethod(m.getMethodDescriptor()) == null && !m.isFinal()) { potentialSuperCall = m; } } }
private JumpInfoFromStackMap getJumpInfoFromStackMap() { IAnalysisCache analysisCache = Global.getAnalysisCache(); XMethod xMethod = XFactory.createXMethod(v.getThisClass(), v.getMethod()); if (xMethod instanceof MethodInfo) { MethodInfo mi = (MethodInfo) xMethod; if (!mi.hasBackBranch()) { return null; } } try { return analysisCache.getMethodAnalysis(JumpInfoFromStackMap.class, xMethod.getMethodDescriptor()); } catch (CheckedAnalysisException e) { AnalysisContext.logError("Error getting jump information from StackMap", e); return null; } }
private JumpInfo getJumpInfo() { IAnalysisCache analysisCache = Global.getAnalysisCache(); XMethod xMethod = XFactory.createXMethod(v.getThisClass(), v.getMethod()); if (xMethod instanceof MethodInfo) { MethodInfo mi = (MethodInfo) xMethod; if (!mi.hasBackBranch()) { return null; } } try { return analysisCache.getMethodAnalysis(JumpInfo.class, xMethod.getMethodDescriptor()); } catch (CheckedAnalysisException e) { AnalysisContext.logError("Error getting jump information", e); return null; } } private JumpInfoFromStackMap getJumpInfoFromStackMap() {
tqa = tqdb.getReturnValue(calledXMethod.getMethodDescriptor(), typeQualifierValue); if (tqa != null) { interproc = true;
TypeQualifierAnnotation tqa = TypeQualifierAnnotation.getValue(tqv, paramFlowValue == FlowValue.ALWAYS ? When.ALWAYS : When.NEVER); tqdb.setParameter(xmethod.getMethodDescriptor(), i, tqv, tqa);
@Override public void visitClassContext(ClassContext classContext) { JavaClass jclass = classContext.getJavaClass(); for (Method method : jclass.getMethods()) { XMethod xmethod = XFactory.createXMethod(classContext.getJavaClass(), method); ParameterProperty nonnullParameters = AnalysisContext.currentAnalysisContext().getUnconditionalDerefParamDatabase() .getProperty(xmethod.getMethodDescriptor()); if (nonnullParameters != null) { for (int p : nonnullParameters.iterable()) { TypeQualifierAnnotation directTypeQualifierAnnotation = TypeQualifierApplications .getDirectTypeQualifierAnnotation(xmethod, p, nonnullTypeQualifierValue); if (directTypeQualifierAnnotation != null && directTypeQualifierAnnotation.when == When.UNKNOWN) { // // The LocalVariableAnnotation is constructed using the // local variable // number of the parameter, not the parameter number. // int paramLocal = xmethod.isStatic() ? p : p + 1; reporter.reportBug(new BugInstance(this, "NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE", NORMAL_PRIORITY).addClassAndMethod(jclass, method).add( LocalVariableAnnotation.getParameterLocalVariableAnnotation(method, paramLocal))); } } } } }
private void killLoadsOfObjectsPassed(InvokeInstruction ins) { try { XMethod called = Hierarchy2.findExactMethod(ins, methodGen.getConstantPool(), Hierarchy.ANY_METHOD); if (called != null ) { NoSideEffectMethodsDatabase nse = Global.getAnalysisCache().getOptionalDatabase(NoSideEffectMethodsDatabase.class); if(nse != null && !nse.is(called.getMethodDescriptor(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ)) { return; } } FieldSummary fieldSummary = AnalysisContext.currentAnalysisContext().getFieldSummary(); Set<XField> touched = fieldSummary.getFieldsWritten(called); if (!touched.isEmpty()) { getFrame().killLoadsOf(touched); } int passed = getNumWordsConsumed(ins); ValueNumber[] arguments = allocateValueNumberArray(passed); getFrame().killLoadsWithSimilarName(ins.getClassName(cpg), ins.getMethodName(cpg)); getFrame().getTopStackWords(arguments); for (ValueNumber v : arguments) { getFrame().killAllLoadsOf(v); } // Too many false-positives for primitives without transitive FieldSummary analysis, // so currently we simply kill any writable primitive on any method call // TODO: implement transitive FieldSummary getFrame().killAllLoads(true); } catch (DataflowAnalysisException e) { AnalysisContext.logError("Error in killLoadsOfObjectsPassed", e); } }