// Scan method for
// - dead stores
// - stores to parameters that are dead upon entry to the method
for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
Location location = i.next();
BugInstance pendingBugReportAboutOverwrittenParameter = null;
try {
WarningPropertySet<WarningProperty> propertySet = new WarningPropertySet<WarningProperty>();
// Skip any instruction which is not a store
if (!isStore(location)) {
continue;
}
// Heuristic: exception handler blocks often contain
// dead stores generated by the compiler.
if (location.getBasicBlock().isExceptionHandler()) {
propertySet.addProperty(DeadLocalStoreProperty.EXCEPTION_HANDLER);
}
InstructionHandle handle = location.getHandle();
int pc = handle.getPosition();
IndexedInstruction ins = (IndexedInstruction) location.getHandle().getInstruction();
int local = ins.getIndex();
// Get live stores at this instruction.
// Note that the analysis also computes which stores were
// killed by a subsequent unconditional store.
BitSet liveStoreSet = llsaDataflow.getAnalysis().getFactAtLocation(location);
// Is store alive?
boolean storeLive = llsaDataflow.getAnalysis().isStoreAlive(liveStoreSet, local);
LocalVariableAnnotation lvAnnotation = LocalVariableAnnotation.getLocalVariableAnnotation(method, location, ins);
String sourceFileName = javaClass.getSourceFileName();
if (lvAnnotation.getName().equals("?")) {
if (sourceFileName.endsWith(".groovy")) {
continue;
}
if (method.getCode().getLocalVariableTable() != null) {
continue;
}
}
SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen,
sourceFileName, location.getHandle());
if (DEBUG) {
System.out.println(" Store at " + sourceLineAnnotation.getStartLine() + "@"
+ location.getHandle().getPosition() + " is " + (storeLive ? "live" : "dead"));
System.out.println("Previous is: " + location.getHandle().getPrev());
}
// Note source lines of live stores.
if (storeLive && sourceLineAnnotation.getStartLine() > 0) {
liveStoreSourceLineSet.set(sourceLineAnnotation.getStartLine());
}
String lvName = lvAnnotation.getName();
if (lvName.charAt(0) == '$' || lvName.charAt(0) == '_') {
propertySet.addProperty(DeadLocalStoreProperty.SYNTHETIC_NAME);
}
if (EXCLUDED_LOCALS.contains(lvName)) {
continue;
}
propertySet.setProperty(DeadLocalStoreProperty.LOCAL_NAME, lvName);
boolean isParameter = local < localsThatAreParameters;
if (isParameter) {
propertySet.addProperty(DeadLocalStoreProperty.IS_PARAMETER);
}
Field shadowedField = null;
for (Field f : javaClass.getFields()) {
if (f.getName().equals(lvName) && f.isStatic() == method.isStatic()) {
shadowedField = f;
propertySet.addProperty(DeadLocalStoreProperty.SHADOWS_FIELD);
break;
}
}
// Is this a store to a parameter which was dead on entry to the
// method?
boolean parameterThatIsDeadAtEntry = isParameter
&& !llsaDataflow.getAnalysis().isStoreAlive(liveStoreSetAtEntry, local);
if (parameterThatIsDeadAtEntry && !complainedAbout.get(local)) {
int priority = storeLive ? LOW_PRIORITY : NORMAL_PRIORITY;
if (shadowedField != null) {
priority--;
}
pendingBugReportAboutOverwrittenParameter = new BugInstance(this, "IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN",
priority).addClassAndMethod(methodGen, sourceFileName).add(lvAnnotation);
if (shadowedField != null) {
pendingBugReportAboutOverwrittenParameter.addField(
FieldAnnotation.fromBCELField(classContext.getJavaClass(), shadowedField)).describe(
FieldAnnotation.DID_YOU_MEAN_ROLE);
}
pendingBugReportAboutOverwrittenParameter.addSourceLine(classContext, methodGen, sourceFileName,
location.getHandle());
complainedAbout.set(local);
}
if (storeLive) {
continue;
}
TypeFrame typeFrame = typeDataflow.getAnalysis().getFactAtLocation(location);
Type typeOfValue = null;
if (typeFrame.isValid() && typeFrame.getStackDepth() > 0) {
typeOfValue = typeFrame.getTopValue();
}
boolean storeOfNull = false;
InstructionHandle prevInsHandle = location.getHandle().getPrev();
if (prevInsHandle != null) {
Instruction prevIns = prevInsHandle.getInstruction();
boolean foundDeadClassInitialization = false;
String initializationOf = null;
if (prevIns instanceof ConstantPushInstruction) {
continue; // not an interesting dead store
} else if (prevIns instanceof GETSTATIC) {
GETSTATIC getStatic = (GETSTATIC) prevIns;
ConstantPoolGen cpg = methodGen.getConstantPool();
foundDeadClassInitialization = getStatic.getFieldName(cpg).startsWith("class$")
&& getStatic.getSignature(cpg).equals("Ljava/lang/Class;");
for (Iterator<Location> j = cfg.locationIterator(); j.hasNext();) {
Location location2 = j.next();
if (location2.getHandle().getPosition() + 15 == location.getHandle().getPosition()) {
Instruction instruction2 = location2.getHandle().getInstruction();
if (instruction2 instanceof LDC) {
Object value = ((LDC) instruction2).getValue(methodGen.getConstantPool());
if (value instanceof String) {
String n = (String) value;
if (n.length() > 0) {