You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
6.9 KiB
274 lines
6.9 KiB
/*
|
|
* Copyright (c) 2015 - present Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
package codetoanalyze.java.infer;
|
|
|
|
import java.util.Iterator;
|
|
|
|
public class AnalysisStops {
|
|
|
|
private native Object externalFunc();
|
|
|
|
public void skipPointerDerefMayCauseLocalFalseNegative() {
|
|
Object ret = externalFunc();
|
|
ret.toString();
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
private Object skipPointerDerefPreventsSpecInferenceRetObj() {
|
|
Object ret = externalFunc();
|
|
ret.toString();
|
|
return new Object();
|
|
}
|
|
|
|
public void skipPointerDerefMayCauseCalleeFalsePositive() {
|
|
Object o = skipPointerDerefPreventsSpecInferenceRetObj();
|
|
o.toString();
|
|
}
|
|
|
|
private int skipPointerDerefPreventsSpecInferenceRetZero() {
|
|
Object ret = externalFunc();
|
|
ret.toString();
|
|
return 0;
|
|
}
|
|
|
|
public void skipPointerDerefMayCauseCalleeFalseNegative() {
|
|
int ret = skipPointerDerefPreventsSpecInferenceRetZero();
|
|
int i = 1 / ret;
|
|
}
|
|
|
|
private void divideByParam(int i) {
|
|
int j = 1 / i;
|
|
}
|
|
|
|
public void skipPointerDerefMayCauseInterprocFalseNegative() {
|
|
int i = skipPointerDerefPreventsSpecInferenceRetZero();
|
|
divideByParam(i);
|
|
}
|
|
|
|
private String castExternalPreventsSpecInference() {
|
|
return (String) externalFunc();
|
|
}
|
|
|
|
public void castFailureOnUndefinedObjMayCauseFalseNegative() {
|
|
castExternalPreventsSpecInference();
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
public void callOnCastUndefinedObjMayCauseFalseNegative() {
|
|
String s = castExternalPreventsSpecInference();
|
|
s.toString();
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
private static class MyObj {
|
|
Object f;
|
|
MyObj rec;
|
|
int i;
|
|
|
|
public int retOne() {
|
|
return 1;
|
|
}
|
|
|
|
public int retZero() {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
private native MyObj externalFunc2();
|
|
|
|
public void callOnUndefinedObjMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
int i = 1 / ret.retZero();
|
|
}
|
|
|
|
public void callOnUndefinedObjMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
int i = 1 / ret.retOne();
|
|
}
|
|
|
|
public void fieldWriteOnUndefinedObjMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
ret.f = new Object();
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
public void fieldWriteOnUndefinedObjMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
ret.f = new Object();
|
|
ret.f.toString();
|
|
}
|
|
|
|
public void fieldReadOnUndefinedObjMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
Object o = ret.f;
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
public void fieldReadOnUndefinedObjMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
Object o = ret.f;
|
|
o.toString();
|
|
}
|
|
|
|
public void recursiveAngelicTypesMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
MyObj rec1 = ret.rec;
|
|
MyObj rec2 = rec1.rec;
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
public void recursiveAngelicTypesMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
MyObj rec1 = ret.rec;
|
|
rec1.rec.toString();
|
|
}
|
|
|
|
public void infiniteMaterializationMayCauseFalseNegative(boolean b) {
|
|
MyObj rec = externalFunc2();
|
|
while (b) {
|
|
rec = rec.rec;
|
|
}
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
public void infiniteMaterializationMayCauseFalsePositive(boolean b) {
|
|
MyObj rec = externalFunc2();
|
|
while (b) {
|
|
rec = rec.rec;
|
|
}
|
|
rec.toString();
|
|
}
|
|
|
|
public void primitiveFieldOfAngelicObjMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
if (ret.i == 0) {
|
|
int i = 1 / 0;
|
|
} else {
|
|
int i = 1 / 0;
|
|
}
|
|
}
|
|
|
|
public void primitiveFieldOfAngelicObjMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
if (ret.i != 0) {
|
|
int i = 1 / ret.i;
|
|
}
|
|
}
|
|
|
|
public void heapFieldOfAngelicObjMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
Object obj = ret.f;
|
|
if (obj == ret.f) {
|
|
int i = 1 / 0;
|
|
}
|
|
}
|
|
|
|
public void heapFieldOfAngelicObjMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
Object obj = ret.f;
|
|
if (obj != ret.f) {
|
|
int i = 1 / 0;
|
|
}
|
|
}
|
|
|
|
public void fieldReadAferCastMayCauseFalseNegative(Iterator<MyObj> iter) {
|
|
MyObj ret = iter.next();
|
|
Object obj = ret.f;
|
|
obj.toString();
|
|
int i = ret.i;
|
|
if (i == 7) {
|
|
int j = 1 / 0;
|
|
}
|
|
}
|
|
|
|
public void derefParam(MyObj obj) {
|
|
Object f = obj.f;
|
|
f.toString();
|
|
}
|
|
|
|
public void fieldReadInCalleeMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
derefParam(ret);
|
|
}
|
|
|
|
public void fieldReadInCalleeMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
ret.f = null;
|
|
derefParam(ret);
|
|
}
|
|
|
|
public void fieldReadInCalleeWithAngelicObjFieldMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
derefParam(ret.rec);
|
|
}
|
|
|
|
public void fieldReadInCalleeWithAngelicObjFieldMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
ret.rec.f = null;
|
|
derefParam(ret.rec);
|
|
}
|
|
|
|
public void accessPathOnParam(MyObj obj) {
|
|
MyObj ret = obj.rec;
|
|
Object f = ret.f;
|
|
f.toString();
|
|
}
|
|
|
|
public void accessPathInCalleeMayCauseFalsePositive() {
|
|
MyObj ret = externalFunc2();
|
|
accessPathOnParam(ret);
|
|
}
|
|
|
|
public void accessPathInCalleeMayCauseFalseNegative() {
|
|
MyObj ret = externalFunc2();
|
|
ret.rec.f = null;
|
|
accessPathOnParam(ret);
|
|
}
|
|
|
|
public void skipFunctionInLoopMayCauseFalseNegative() {
|
|
Object o = null;
|
|
for (int i = 0; i < 10; i++) {
|
|
externalFunc();
|
|
}
|
|
o.toString();
|
|
}
|
|
|
|
// will fail to find error unless spec inference succeeds for all callees
|
|
public void specInferenceMayFailAndCauseFalseNegative(boolean b, Iterator<MyObj> iter) {
|
|
skipPointerDerefMayCauseLocalFalseNegative();
|
|
skipPointerDerefPreventsSpecInferenceRetObj();
|
|
skipPointerDerefPreventsSpecInferenceRetZero();
|
|
skipPointerDerefMayCauseCalleeFalseNegative();
|
|
skipPointerDerefMayCauseInterprocFalseNegative();
|
|
castFailureOnUndefinedObjMayCauseFalseNegative();
|
|
callOnCastUndefinedObjMayCauseFalseNegative();
|
|
callOnUndefinedObjMayCauseFalseNegative();
|
|
callOnUndefinedObjMayCauseFalsePositive();
|
|
fieldWriteOnUndefinedObjMayCauseFalseNegative();
|
|
fieldWriteOnUndefinedObjMayCauseFalsePositive();
|
|
fieldReadOnUndefinedObjMayCauseFalseNegative();
|
|
fieldReadOnUndefinedObjMayCauseFalsePositive();
|
|
recursiveAngelicTypesMayCauseFalseNegative();
|
|
recursiveAngelicTypesMayCauseFalsePositive();
|
|
infiniteMaterializationMayCauseFalseNegative(b);
|
|
infiniteMaterializationMayCauseFalsePositive(b);
|
|
primitiveFieldOfAngelicObjMayCauseFalsePositive();
|
|
primitiveFieldOfAngelicObjMayCauseFalseNegative();
|
|
heapFieldOfAngelicObjMayCauseFalsePositive();
|
|
heapFieldOfAngelicObjMayCauseFalseNegative();
|
|
fieldReadAferCastMayCauseFalseNegative(iter);
|
|
fieldReadInCalleeMayCauseFalsePositive();
|
|
fieldReadInCalleeWithAngelicObjFieldMayCauseFalsePositive();
|
|
accessPathInCalleeMayCauseFalsePositive();
|
|
int i = 1 / 0;
|
|
}
|
|
|
|
}
|