public static Set<ValueNumber> checkNonNullParams( Location location, ValueNumberFrame vnaFrame, ConstantPoolGen constantPool, @CheckForNull Method method, @CheckForNull IsNullValueFrame invFrame) throws DataflowAnalysisException { if (invFrame != null && !invFrame.isValid()) { return Collections.emptySet(); } INullnessAnnotationDatabase database = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction(); XMethod called = XFactory.createXMethod(inv, constantPool); SignatureParser sigParser = new SignatureParser(called.getSignature()); int numParams = sigParser.getNumParameters(); Set<ValueNumber> result = new HashSet<ValueNumber>(); Iterator<String> parameterIterator = sigParser.parameterSignatureIterator(); for (int i = 0; i < numParams; i++) { String parameterSignature = parameterIterator.next(); char firstChar = parameterSignature.charAt(0); if (firstChar != 'L' && firstChar != '[') { continue; } int offset = sigParser.getSlotsFromTopOfStackForParameter(i); if (invFrame != null) { int slot = invFrame.getStackLocation(offset); if (!reportDereference(invFrame, slot)) { continue; } } if (database.parameterMustBeNonNull(called, i)) { int catchSizeNPE = Util.getSizeOfSurroundingTryBlock( method, "java/lang/NullPointerException", location.getHandle().getPosition()); int catchSizeNFE = Util.getSizeOfSurroundingTryBlock( method, "java/lang/NumberFormatException", location.getHandle().getPosition()); if (catchSizeNPE == Integer.MAX_VALUE && (!"java.lang.Integer".equals(called.getClassName()) || catchSizeNFE == Integer.MAX_VALUE)) { // Get the corresponding value number ValueNumber vn = vnaFrame.getArgument(inv, constantPool, i, sigParser); result.add(vn); } } } return result; }
public static Set<ValueNumber> checkUnconditionalDerefDatabase( Location location, ValueNumberFrame vnaFrame, ConstantPoolGen constantPool, @CheckForNull IsNullValueFrame invFrame, TypeDataflow typeDataflow) throws DataflowAnalysisException { if (invFrame != null && !invFrame.isValid()) { return Collections.emptySet(); } InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction(); SignatureParser sigParser = new SignatureParser(inv.getSignature(constantPool)); int numParams = sigParser.getNumParameters(); if (numParams == 0 || !sigParser.hasReferenceParameters()) { return Collections.emptySet(); } ParameterNullnessPropertyDatabase database = AnalysisContext.currentAnalysisContext().getUnconditionalDerefParamDatabase(); if (database == null) { if (DEBUG_CHECK_CALLS) { System.out.println("no database!"); } return Collections.emptySet(); } TypeFrame typeFrame = typeDataflow.getFactAtLocation(location); if (!typeFrame.isValid()) { if (DEBUG_CHECK_CALLS) { System.out.println("invalid type frame!"); } return Collections.emptySet(); } try { Set<XMethod> targetSet = Hierarchy2.resolveMethodCallTargets(inv, typeFrame, constantPool); if (targetSet.isEmpty()) { return Collections.emptySet(); } if (DEBUG_CHECK_CALLS) { System.out.println("target set size: " + targetSet.size()); } // Compute the intersection of all properties ParameterProperty derefParamSet = null; for (XMethod target : targetSet) { if (target.isStub()) { continue; } if (DEBUG_CHECK_CALLS) { System.out.print("Checking: " + target + ": "); } ParameterProperty targetDerefParamSet = database.getProperty(target.getMethodDescriptor()); if (targetDerefParamSet == null) { // Hmm...no information for this target. // assume it doesn't dereference anything if (DEBUG_CHECK_CALLS) { System.out.println("==> no information, assume no guaranteed dereferences"); } return Collections.emptySet(); } if (DEBUG_CHECK_CALLS) { System.out.println("==> " + targetDerefParamSet); } if (derefParamSet == null) { derefParamSet = new ParameterProperty(); derefParamSet.copyFrom(targetDerefParamSet); } else { derefParamSet.intersectWith(targetDerefParamSet); } } if (derefParamSet == null || derefParamSet.isEmpty()) { if (DEBUG) { System.out.println("** Nothing"); } return Collections.emptySet(); } if (DEBUG_CHECK_CALLS) { System.out.println( "** Summary of call @ " + location.getHandle().getPosition() + ": " + derefParamSet); } HashSet<ValueNumber> requiredToBeNonnull = new HashSet<ValueNumber>(); for (int i = 0; i < numParams; i++) { if (!derefParamSet.hasProperty(i)) { continue; } int argSlot = vnaFrame.getStackLocation(sigParser.getSlotsFromTopOfStackForParameter(i)); if (invFrame != null && !reportDereference(invFrame, argSlot)) { continue; } if (DEBUG_CHECK_CALLS) { System.out.println( " dereference @ " + location.getHandle().getPosition() + " of parameter " + i); } requiredToBeNonnull.add(vnaFrame.getValue(argSlot)); } return requiredToBeNonnull; } catch (ClassNotFoundException e) { AnalysisContext.reportMissingClass(e); } return Collections.emptySet(); }