/** * If this is a putfield or putstatic instruction, check to see if the field is @NonNull, and * treat it as dereferences. * * @param location the Location of the instruction * @param vnaFrame the ValueNumberFrame at the Location of the instruction * @param fact the dataflow value to modify * @throws DataflowAnalysisException */ private void checkNonNullPutField( Location location, ValueNumberFrame vnaFrame, UnconditionalValueDerefSet fact) throws DataflowAnalysisException { INullnessAnnotationDatabase database = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); FieldInstruction fieldIns = (FieldInstruction) location.getHandle().getInstruction(); XField field = XFactory.createXField(fieldIns, methodGen.getConstantPool()); char firstChar = field.getSignature().charAt(0); if (firstChar != 'L' && firstChar != '[') { return; } NullnessAnnotation resolvedAnnotation = database.getResolvedAnnotation(field, true); if (resolvedAnnotation == NullnessAnnotation.NONNULL) { IsNullValueFrame invFrame = invDataflow.getFactAtLocation(location); if (!invFrame.isValid()) { return; } IsNullValue value = invFrame.getTopValue(); if (reportDereference(value)) { ValueNumber vn = vnaFrame.getTopValue(); fact.addDeref(vn, location); } } }
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; }
/** * If this is a method call instruction, check to see if any of the parameters are @NonNull, and * treat them as dereferences. * * @param location the Location of the instruction * @param vnaFrame the ValueNumberFrame at the Location of the instruction * @param fact the dataflow value to modify * @throws DataflowAnalysisException */ private void checkNonNullReturnValue( XMethod thisMethod, Location location, ValueNumberFrame vnaFrame, UnconditionalValueDerefSet fact) throws DataflowAnalysisException { INullnessAnnotationDatabase database = AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase(); if (database.getResolvedAnnotation(thisMethod, true) != NullnessAnnotation.NONNULL) { return; } if (reportPotentialDereference(location, invDataflow.getFactAtLocation(location))) { ValueNumber vn = vnaFrame.getTopValue(); fact.addDeref(vn, location); } }