keys to distinguish @NotNull and @Nullable parameters analyses

This commit is contained in:
Ilya Klyuchnikov
2014-08-25 18:30:42 +04:00
parent 274ca5ceef
commit e88755962b
6 changed files with 27 additions and 62 deletions
@@ -277,10 +277,11 @@ public class BytecodeAnalysisConverter {
return 0;
} else if (dir instanceof In) {
In in = (In)dir;
return 8 * in.paramId() + 1;
// nullity mask is 0/1
return 8 * in.paramId() + 1 + in.nullityMask;
} else {
InOut inOut = (InOut)dir;
return 8 * inOut.paramId() + 2 + inOut.valueId();
return 8 * inOut.paramId() + 3 + inOut.valueId();
}
}
@@ -292,11 +293,11 @@ public class BytecodeAnalysisConverter {
else {
int paramId = directionKey / 8;
int subDirection = directionKey % 8;
if (subDirection == 1) {
return new In(paramId);
if (subDirection <= 2) {
return new In(paramId, subDirection - 1);
}
else {
return new InOut(paramId, Value.values()[subDirection - 2]);
return new InOut(paramId, Value.values()[subDirection - 3]);
}
}
}
@@ -232,13 +232,13 @@ public class ClassDataIndexer implements DataIndexer<Bytes, HEquations, FileCont
if (isReferenceArg) {
if (leakingParameters[i]) {
Equation<Key, Value> notNullParamEquation = new NonNullInAnalysis(richControlFlow, new In(i), stable).analyze();
Equation<Key, Value> notNullParamEquation = new NonNullInAnalysis(richControlFlow, new In(i, In.NOT_NULL), stable).analyze();
notNullParam = notNullParamEquation.rhs.equals(FINAL_NOT_NULL);
result.add(notNullParamEquation);
}
else {
// parameter is not leaking, so it is definitely NOT @NotNull
result.add(new Equation<Key, Value>(new Key(method, new In(i), stable), FINAL_TOP));
result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NOT_NULL), stable), FINAL_TOP));
}
}
if (isReferenceArg && isInterestingResult) {
@@ -335,7 +335,7 @@ public class ClassDataIndexer implements DataIndexer<Bytes, HEquations, FileCont
boolean isBooleanArg = ASMUtils.isBooleanType(argType);
if (isReferenceArg) {
result.add(new Equation<Key, Value>(new Key(method, new In(i), stable), FINAL_TOP));
result.add(new Equation<Key, Value>(new Key(method, new In(i, In.NOT_NULL), stable), FINAL_TOP));
}
if (isReferenceArg && isInterestingResult) {
result.add(new Equation<Key, Value>(new Key(method, new InOut(i, Value.Null), stable), FINAL_TOP));
@@ -106,7 +106,7 @@ final class CombinedSingleAnalysis {
}
final Equation<Key, Value> notNullParamEquation(int i, boolean stable) {
final Key key = new Key(method, new In(i), stable);
final Key key = new Key(method, new In(i, In.NOT_NULL), stable);
final Result<Key, Value> result;
if (interpreter.dereferenced[i]) {
result = new Final<Key, Value>(Value.NotNull);
@@ -367,7 +367,7 @@ final class CombinedInterpreter extends BasicInterpreter {
npKeys = new HashSet<Key>();
callDerefs[n] = npKeys;
}
npKeys.add(new Key(method, new In(i - shift), stable));
npKeys.add(new Key(method, new In(i - shift, In.NOT_NULL), stable));
}
}
}
@@ -52,20 +52,17 @@ enum Value {
Bot, NotNull, Null, True, False, Top
}
interface Direction {
static final int OUT_DIRECTION = 0;
static final int IN_DIRECTION = 1;
static final int INOUT_DIRECTION = 2;
int directionId();
int paramId();
int valueId();
}
interface Direction {}
final class In implements Direction {
static final int NOT_NULL = 0;
static final int NULLABLE = 1;
final int paramIndex;
final int nullityMask;
In(int paramIndex) {
In(int paramIndex, int nullityMask) {
this.paramIndex = paramIndex;
this.nullityMask = nullityMask;
}
@Override
@@ -79,28 +76,19 @@ final class In implements Direction {
if (o == null || getClass() != o.getClass()) return false;
In in = (In) o;
if (paramIndex != in.paramIndex) return false;
if (nullityMask != in.nullityMask) return false;
return true;
}
@Override
public int hashCode() {
return paramIndex;
return 31*paramIndex + nullityMask;
}
@Override
public int directionId() {
return IN_DIRECTION;
}
@Override
public int paramId() {
return paramIndex;
}
@Override
public int valueId() {
return 0;
}
}
final class InOut implements Direction {
@@ -137,17 +125,10 @@ final class InOut implements Direction {
return "InOut " + paramIndex + " " + inValue.toString();
}
@Override
public int directionId() {
return INOUT_DIRECTION;
}
@Override
public int paramId() {
return paramIndex;
}
@Override
public int valueId() {
return inValue.ordinal();
}
@@ -168,21 +149,6 @@ final class Out implements Direction {
public boolean equals(Object obj) {
return obj instanceof Out;
}
@Override
public int directionId() {
return OUT_DIRECTION;
}
@Override
public int paramId() {
return 0;
}
@Override
public int valueId() {
return 0;
}
}
final class Key {
@@ -219,10 +185,6 @@ final class Key {
@Override
public String toString() {
return "" + method + ' ' + direction + ' ' + stable;
return method + " " + direction + " " + stable;
}
}
class LimitReachedException extends RuntimeException {
}
@@ -607,10 +607,12 @@ class NullableInAnalysis extends Analysis<PResult> {
abstract class NullityInterpreter extends BasicInterpreter {
boolean top = false;
final boolean nullableAnalysis;
final int nullityMask;
private PResult subResult = Identity;
NullityInterpreter(boolean nullableAnalysis) {
NullityInterpreter(boolean nullableAnalysis, int nullityMask) {
this.nullableAnalysis = nullableAnalysis;
this.nullityMask = nullityMask;
}
abstract PResult combine(PResult res1, PResult res2) throws AnalyzerException;
@@ -731,7 +733,7 @@ abstract class NullityInterpreter extends BasicInterpreter {
Method method = new Method(methodNode.owner, methodNode.name, methodNode.desc);
for (int i = shift; i < values.size(); i++) {
if (values.get(i) instanceof ParamValue) {
subResult = combine(subResult, new ConditionalNPE(new Key(method, new In(i - shift), stable)));
subResult = combine(subResult, new ConditionalNPE(new Key(method, new In(i - shift, nullityMask), stable)));
}
}
break;
@@ -744,7 +746,7 @@ abstract class NullityInterpreter extends BasicInterpreter {
class NotNullInterpreter extends NullityInterpreter {
NotNullInterpreter() {
super(false);
super(false, In.NOT_NULL);
}
@Override
@@ -756,7 +758,7 @@ class NotNullInterpreter extends NullityInterpreter {
class NullableInterpreter extends NullityInterpreter {
NullableInterpreter() {
super(true);
super(true, In.NULLABLE);
}
@Override
@@ -162,7 +162,7 @@ public class ProjectBytecodeAnalysis {
PsiElement gParent = parent.getParent();
if (gParent instanceof PsiMethod) {
final int index = ((PsiParameterList)parent).getParameterIndex((PsiParameter)owner);
return BytecodeAnalysisConverter.psiKey((PsiMethod)gParent, new In(index), md);
return BytecodeAnalysisConverter.psiKey((PsiMethod)gParent, new In(index, In.NOT_NULL), md);
}
}
}