/** * If feature is enabled, suppress warnings where there is at least one live * store on the line where the warning would be reported. * * @param accumulator * BugAccumulator containing warnings for method * @param liveStoreSourceLineSet * bitset of lines where at least one live store was seen */ private void suppressWarningsIfOneLiveStoreOnLine(BugAccumulator accumulator, BitSet liveStoreSourceLineSet) { if (!SUPPRESS_IF_AT_LEAST_ONE_LIVE_STORE_ON_LINE) { return; } // Eliminate any accumulated warnings for instructions // that (due to inlining) *can* be live stores. entryLoop: for (Iterator<? extends BugInstance> i = accumulator.uniqueBugs().iterator(); i.hasNext();) { for (SourceLineAnnotation annotation : accumulator.locations(i.next())) { if (liveStoreSourceLineSet.get(annotation.getStartLine())) { // This instruction can be a live store; don't report // it as a warning. i.remove(); continue entryLoop; } } } }
String fullPath = "???"; SourceLineAnnotation line = bugInstance.getPrimarySourceLineAnnotation(); lineStart = line.getStartLine(); lineEnd = line.getEndLine(); SourceFinder sourceFinder = AnalysisContext.currentAnalysisContext().getSourceFinder(); String pkgName = line.getPackageName(); try { fullPath = sourceFinder.findSourceFile(pkgName, line.getSourceFile()).getFullFileName(); } catch (IOException e) { if ("".equals(pkgName)) { fullPath = line.getSourceFile(); } else { fullPath = pkgName.replace('.', '/') + "/" + line.getSourceFile(); outputStream.print(fullPath + ":" + lineStart + ":" + lineEnd + " " + bugInstance.getMessage()); switch (bugInstance.getPriority()) { case Priorities.EXP_PRIORITY: outputStream.print(" (E) ");
/** * Add a source line annotation for instruction currently being visited by * given visitor. Note that if the method does not have line number * information, then no source line annotation will be added. * * @param visitor * a BytecodeScanningDetector visitor that is currently visiting * the instruction * @return this object */ @Nonnull public BugInstance addSourceLine(BytecodeScanningDetector visitor) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(visitor); if (sourceLineAnnotation != null) { add(sourceLineAnnotation); } return this; }
static SourceLineAnnotation obfuscate(SourceLineAnnotation m) { SourceLineAnnotation result = new SourceLineAnnotation(hashClass(m.getClassName()), hashFilename(m.getSourceFile()), m.getStartLine(), m.getEndLine(), m.getStartBytecode(), m.getEndBytecode()); result.setDescription(m.getDescription()); return result; }
static String fullPath(SourceLineAnnotation src) { return src.getPackageName().replace('.', File.separatorChar) + File.separatorChar + src.getSourceFile(); }
public static String getOrGuessSourceFile(SourceLineAnnotation source) { if (source.isSourceFileKnown()) { return source.getSourceFile(); } String baseClassName = source.getClassName(); int i = baseClassName.lastIndexOf('.'); baseClassName = baseClassName.substring(i + 1); int j = baseClassName.indexOf('$'); if (j >= 0) { baseClassName = baseClassName.substring(0, j); } return baseClassName + ".java"; }
BitSet knownNull = new BitSet(); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, method, loc); if (sourceLineAnnotation == null) { continue; int startLine = sourceLineAnnotation.getStartLine(); if (startLine == -1) { knownNullLocations.add(sourceLineAnnotation); } else if (!knownNull.get(startLine)) { knownNull.set(startLine); knownNullLocations.add(sourceLineAnnotation); if (!hasManyPreceedingNullTests(sourceLineAnnotation.getStartBytecode())) { hasManyNullTests = false; source = knownNullLocations.iterator().next().getEndBytecode(); int pos = loc.getHandle().getPosition(); if (pos != source + 3) { SourceLineAnnotation.fromVisitedInstruction(classContext, method, loc)); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, method, assignedNull); if (sourceLineAnnotation != null) { int startLine = sourceLineAnnotation.getStartLine();
IsNullValueDataflow nullValueDataflow = classContext.getIsNullValueDataflow(method); MethodGen methodGen = classContext.getMethodGen(method); String sourceFile = classContext.getJavaClass().getSourceFileName(); if (lineMentionedMultipleTimes.cardinality() > 0) { linesWithLoadsOfNotDefinitelyNullValues = new BitSet(); LineNumberTable lineNumbers = method.getLineNumberTable(); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction ins = handle.getInstruction(); if (!(ins instanceof ALOAD)) { continue; SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); SourceLineAnnotation prevSourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, prevHandle); int startLine = sourceLineAnnotation.getStartLine(); int previousLine = prevSourceLineAnnotation.getEndLine(); if (startLine < previousLine) { new BugInstance(this, "NP_LOAD_OF_KNOWN_NULL_VALUE", priority).addClassAndMethod(methodGen, sourceFile) .addOptionalAnnotation(variableAnnotation), sourceLineAnnotation);
System.out.println(" Analyzing method " + classContext.getJavaClass().getClassName() + "." + method.getName()); Dataflow<BitSet, LiveLocalStoreAnalysis> llsaDataflow = classContext.getLiveLocalStoreDataflow(method); BitSet complainedAbout = new BitSet(); TypeDataflow typeDataflow = classContext.getTypeDataflow(method); BitSet liveStoreSourceLineSet = new BitSet(); int pc = handle.getPosition(); IndexedInstruction ins = (IndexedInstruction) location.getHandle().getInstruction(); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFileName, location.getHandle()); System.out.println(" Store at " + sourceLineAnnotation.getStartLine() + "@" + location.getHandle().getPosition() + " is " + (storeLive ? "live" : "dead")); if (storeLive && sourceLineAnnotation.getStartLine() > 0) { liveStoreSourceLineSet.set(sourceLineAnnotation.getStartLine()); for (Field f : javaClass.getFields()) { priority--; if (occurrences > 2 || sourceLineAnnotation.getStartLine() > 0 && linesMentionedMultipleTimes.get(sourceLineAnnotation.getStartLine())) { propertySet.addProperty(DeadLocalStoreProperty.CLONED_STORE);
/** * Add a method annotation. If this is the first method annotation added, it * becomes the primary method annotation. If the method has source line * information, then a SourceLineAnnotation is added to the method. * * @param javaClass * the class the method is defined in * @param method * the method * @return this object */ @Nonnull public BugInstance addMethod(JavaClass javaClass, Method method) { MethodAnnotation methodAnnotation = new MethodAnnotation(javaClass.getClassName(), method.getName(), method.getSignature(), method.isStatic()); SourceLineAnnotation methodSourceLines = SourceLineAnnotation.forEntireMethod(javaClass, method); methodAnnotation.setSourceLines(methodSourceLines); addMethod(methodAnnotation); return this; }
/** * Add source line annotation for given Location in a method. * * @param classContext * the ClassContext * @param method * the Method * @param handle * InstructionHandle of an instruction in the method * @return this BugInstance */ @Nonnull public BugInstance addSourceLine(ClassContext classContext, Method method, InstructionHandle handle) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, method, handle.getPosition()); if (sourceLineAnnotation != null) { add(sourceLineAnnotation); } return this; }
if (bytecodeSet.get(Const.INSTANCEOF) || bytecodeSet.get(Const.CHECKCAST)) { return; ConstantPoolGen cpg = classContext.getConstantPoolGen(); String sourceFile = classContext.getJavaClass().getSourceFileName(); if (DEBUG) { String methodName = methodGen.getClassName() + "." + methodGen.getName(); Location location = i.next(); InstructionHandle handle = location.getHandle(); Instruction ins = handle.getInstruction(); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); bugReporter.reportBug(new BugInstance(this, "DMI_NONSERIALIZABLE_OBJECT_WRITTEN", isSerializable < 0.15 ? HIGH_PRIORITY : isSerializable > 0.5 ? LOW_PRIORITY : NORMAL_PRIORITY) .addClassAndMethod(methodGen, sourceFile).addType(problem).describe(TypeAnnotation.FOUND_ROLE) .addSourceLine(sourceLineAnnotation));
String sourceFile = classContext.getJavaClass().getSourceFileName(); if (DEBUG) { System.out.println("Checking " + methodName); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); if (ins instanceof CHECKCAST) { int pc = handle.getPosition(); Instruction ins = handle.getInstruction(); if (line > 0 && linesMentionedMultipleTimes.get(line)) { split = true; SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); assert castSig.length() > 1; if (!isCast) { accumulator.accumulateBug(new BugInstance(this, "NP_NULL_INSTANCEOF", split ? LOW_PRIORITY : NORMAL_PRIORITY) .addClassAndMethod(methodGen, sourceFile).addType(castSig), sourceLineAnnotation); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); int catchSize = Util.getSizeOfSurroundingTryBlock(classContext.getJavaClass().getConstantPool(), method.getCode(), "java/lang/ClassCastException", position);
private void analyzeMethod(ClassContext classContext, Method method) throws DataflowAnalysisException, CFGBuilderException { if (BCELUtil.isSynthetic(method) || (method.getAccessFlags() & Const.ACC_BRIDGE) == Const.ACC_BRIDGE) { return; TypeDataflow typeDataflow = classContext.getTypeDataflow(method); String sourceFileName = javaClass.getSourceFileName(); Instruction ins = handle.getInstruction(); Type objType = typeFrame.getStackValue(2); if(extendsConcurrentMap(ClassName.toDottedClassName(ClassName.fromFieldSignature(objType.getSignature())))) { InstructionHandle next = handle.getNext(); boolean isIgnored = next != null && next.getInstruction() instanceof POP; if (vna.getValue(pos).equals(vn) && live.get(pos)) { BugAnnotation ba = ValueNumberSourceInfo.findAnnotationFromValueNumber(method, location, vn, vnaDataflow.getFactAtLocation(location), "VALUE_OF"); Type type = typeFrame.getTopValue(); int priority = getPriorityForBeingMutable(type); BugInstance bugInstance = new BugInstance(this, pattern, priority) .addClassAndMethod(methodGen, sourceFileName).addCalledMethod(methodGen, invoke) .add(new TypeAnnotation(type)).add(ba); SourceLineAnnotation where = SourceLineAnnotation.fromVisitedInstruction(classContext, method, location); accumulator.accumulateBug(bugInstance, where);
return; Instruction ins = location.getHandle().getInstruction(); int opcode = ins.getOpcode(); int offset = 1; return; SourceLineAnnotation sourceLine = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, location.getHandle()); int line = sourceLine.getStartLine(); BitSet occursMultipleTimes = classContext.linesMentionedMultipleTimes(method); if (line > 0 && occursMultipleTimes.get(line)) { return; BugInstance bug = new BugInstance(this, prefix + op, priority).addClassAndMethod(methodGen, sourceFile); if (ins instanceof InvokeInstruction) { bug.addCalledMethod(classContext.getConstantPoolGen(), (InvokeInstruction) ins);
SourceLineAnnotation source = SourceLineAnnotation.fromVisitedInstruction(this); boolean possibleClone = source.getStartLine() > 0 && linesMentionedMultipleTimes.get(source.getStartLine()); LineNumberTable lineNumberTable = getCode().getLineNumberTable(); int linesDifference = 0; BugInstance bug = new BugInstance(this, "SA_FIELD_SELF_" + op, priority) .addClassAndMethod(this).addField(field0);
&& (target.isEmpty() || isGoto(target.getFirstInstruction().getInstruction())); if (!empty) { try { if (!empty && !previouslyDeadBlocks.get(target.getLabel())) { if (DEBUG) { System.out.println("target was alive previously"); boolean valueIsNull = true; String warning; int pc = location.getHandle().getPosition(); OpcodeStack stack = null; OpcodeStack.Item item1 = null; Instruction ins = location.getHandle().getInstruction(); BugInstance bugInstance = new BugInstance(this, warning, priority).addClassAndMethod(classContext.getJavaClass(), method); LocalVariableAnnotation fallback = new LocalVariableAnnotation("?", -1, -1); boolean foundSource = bugInstance.tryAddingOptionalUniqueAnnotations(variableAnnotation, BugInstance.getFieldOrMethodValueSource(item1), BugInstance.getFieldOrMethodValueSource(item2)); SourceLineAnnotation sourceLine = SourceLineAnnotation.fromVisitedInstruction(classContext, method, location); sourceLine.setDescription("SOURCE_REDUNDANT_NULL_CHECK"); bugAccumulator.accumulateBug(bugInstance, sourceLine);
for (Method m : getThisClass().getMethods()) { if (m.getName().equals(upcall.getName()) && m.getSignature().equals(upcall.getSignature())) { upcallMethod = m; break; SourceLineAnnotation fieldSetAt = SourceLineAnnotation.fromVisitedInstruction(getThisClass(), upcallMethod, pc); BugInstance bug = new BugInstance(this, "UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR", priority).addClassAndMethod( this).addField(f); bug.addMethod(p.method).describe(MethodAnnotation.METHOD_SUPERCLASS_CONSTRUCTOR) .addSourceLine(p.getSourceLineAnnotation()).describe(SourceLineAnnotation.ROLE_CALLED_FROM_SUPERCLASS_AT)
/** * Create a SourceLineAnnotation covering an entire method. * * @param javaClass * JavaClass containing the method * @param method * the method * @return a SourceLineAnnotation for the entire method */ public static SourceLineAnnotation forEntireMethod(JavaClass javaClass, @CheckForNull Method method) { String sourceFile = javaClass.getSourceFileName(); if (method == null) { return createUnknown(javaClass.getClassName(), sourceFile); } Code code = method.getCode(); LineNumberTable lineNumberTable = method.getLineNumberTable(); if (code == null || lineNumberTable == null) { return createUnknown(javaClass.getClassName(), sourceFile); } return forEntireMethod(javaClass.getClassName(), sourceFile, lineNumberTable, code.getLength()); }
pendingUnreachableBranch = new BugInstance(this, "TESTING", NORMAL_PRIORITY) .addClassAndMethod(this).addString("Unreachable loop body").addSourceLineRange(this, becameTop, getPC()); priority--; if (!targetClass.isPublic()) { priority++; SourceLineAnnotation where; if (index.getPC() >= 0) { where = SourceLineAnnotation.fromVisitedInstruction(this, index.getPC()); } else { where = SourceLineAnnotation.fromVisitedInstruction(this); if ((getNameConstantOperand().startsWith("assert") || getNameConstantOperand().startsWith("fail")) && "run".equals(getMethodName()) && implementsRunnable(getThisClass())) { int size1 = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getMethod().getCode(), "java/lang/Throwable", getPC()); int size2 = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getMethod().getCode(), "java/lang/Error", getPC()); int size3 = Util.getSizeOfSurroundingTryBlock(getConstantPool(), getMethod().getCode(), "java/lang/AssertionFailureError", getPC()); int size = Math.min(Math.min(size1, size2), size3); try { JavaClass targetClass = AnalysisContext.currentAnalysisContext().lookupClass(dottedClassName); if (!targetClass.getSuperclassName().startsWith("junit")) { break AssertInvokedFromRun;