if (cfg.isFlagSet(CFG.FOUND_INEXACT_UNCONDITIONAL_THROWERS)) {
return;
}
BitSet liveStoreSetAtEntry = llsaDataflow.getAnalysis().getResultFact(cfg.getEntry());
BitSet complainedAbout = new BitSet();
TypeDataflow typeDataflow = classContext.getTypeDataflow(method);
// Get number of locals that are parameters.
int localsThatAreParameters = PreorderVisitor.getNumberArguments(method.getSignature());
if (!method.isStatic()) {
localsThatAreParameters++;
}
// Scan method to determine number of loads, stores, and increments
// of local variables.
countLocalStoresLoadsAndIncrements(localStoreCount, localLoadCount, localIncrementCount, cfg);
for (int i = 0; i < localsThatAreParameters; i++) {
localStoreCount[i]++;
}
// For each source line, keep track of # times
// the line was a live store. This can eliminate false positives
// due to inlining of finally blocks.
BitSet liveStoreSourceLineSet = new BitSet();
// 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();
}