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.
271 lines
6.9 KiB
271 lines
6.9 KiB
4 years ago
|
/*
|
||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||
|
*
|
||
|
* This source code is licensed under the MIT license found in the
|
||
|
* LICENSE file in the root directory of this source tree.
|
||
|
*/
|
||
|
|
||
|
package codetoanalyze.java.infer;
|
||
|
|
||
|
import java.util.Iterator;
|
||
|
|
||
|
public class AnalysisStops {
|
||
|
|
||
|
private native Object externalFunc();
|
||
|
|
||
|
public void skipPointerDerefMayCauseLocalFalseNegativeBad() {
|
||
|
Object ret = externalFunc();
|
||
|
ret.toString();
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
|
||
|
private Object skipPointerDerefPreventsSpecInferenceRetObj() {
|
||
|
Object ret = externalFunc();
|
||
|
ret.toString();
|
||
|
return new Object();
|
||
|
}
|
||
|
|
||
|
public void skipPointerDerefMayCauseCalleeFalsePositiveOk() {
|
||
|
Object o = skipPointerDerefPreventsSpecInferenceRetObj();
|
||
|
o.toString();
|
||
|
}
|
||
|
|
||
|
private int skipPointerDerefPreventsSpecInferenceRetZero() {
|
||
|
Object ret = externalFunc();
|
||
|
ret.toString();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public void skipPointerDerefMayCauseCalleeFalseNegativeBad() {
|
||
|
int ret = skipPointerDerefPreventsSpecInferenceRetZero();
|
||
|
int i = 1 / ret;
|
||
|
}
|
||
|
|
||
|
private void divideByParam(int i) {
|
||
|
int j = 1 / i;
|
||
|
}
|
||
|
|
||
|
public void skipPointerDerefMayCauseInterprocFalseNegativeBad() {
|
||
|
int i = skipPointerDerefPreventsSpecInferenceRetZero();
|
||
|
divideByParam(i);
|
||
|
}
|
||
|
|
||
|
private String castExternalPreventsSpecInference() {
|
||
|
return (String) externalFunc();
|
||
|
}
|
||
|
|
||
|
public void castFailureOnUndefinedObjMayCauseFalseNegativeBad() {
|
||
|
castExternalPreventsSpecInference();
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
|
||
|
public void callOnCastUndefinedObjMayCauseFalseNegativeBad() {
|
||
|
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 callOnUndefinedObjMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
int i = 1 / ret.retZero();
|
||
|
}
|
||
|
|
||
|
public void callOnUndefinedObjMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
int i = 1 / ret.retOne();
|
||
|
}
|
||
|
|
||
|
public void fieldWriteOnUndefinedObjMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
ret.f = new Object();
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
|
||
|
public void fieldWriteOnUndefinedObjMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
ret.f = new Object();
|
||
|
ret.f.toString();
|
||
|
}
|
||
|
|
||
|
public void fieldReadOnUndefinedObjMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
Object o = ret.f;
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
|
||
|
public void fieldReadOnUndefinedObjMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
Object o = ret.f;
|
||
|
o.toString();
|
||
|
}
|
||
|
|
||
|
public void recursiveAngelicTypesMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
MyObj rec1 = ret.rec;
|
||
|
MyObj rec2 = rec1.rec;
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
|
||
|
public void recursiveAngelicTypesMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
MyObj rec1 = ret.rec;
|
||
|
rec1.rec.toString();
|
||
|
}
|
||
|
|
||
|
public void infiniteMaterializationMayCauseFalseNegativeBad(boolean b) {
|
||
|
MyObj rec = externalFunc2();
|
||
|
while (b) {
|
||
|
rec = rec.rec;
|
||
|
}
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
|
||
|
public void infiniteMaterializationMayCauseFalsePositiveOk(boolean b) {
|
||
|
MyObj rec = externalFunc2();
|
||
|
while (b) {
|
||
|
rec = rec.rec;
|
||
|
}
|
||
|
rec.toString();
|
||
|
}
|
||
|
|
||
|
public void primitiveFieldOfAngelicObjMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
if (ret.i == 0) {
|
||
|
int i = 1 / 0;
|
||
|
} else {
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void primitiveFieldOfAngelicObjMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
if (ret.i != 0) {
|
||
|
int i = 1 / ret.i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void heapFieldOfAngelicObjMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
Object obj = ret.f;
|
||
|
if (obj == ret.f) {
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void heapFieldOfAngelicObjMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
Object obj = ret.f;
|
||
|
if (obj != ret.f) {
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void fieldReadAferCastMayCauseFalseNegativeBad(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 derefParamOk(MyObj obj) {
|
||
|
Object f = obj.f;
|
||
|
f.toString();
|
||
|
}
|
||
|
|
||
|
public void fieldReadInCalleeMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
derefParamOk(ret);
|
||
|
}
|
||
|
|
||
|
public void fieldReadInCalleeMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
ret.f = null;
|
||
|
derefParamOk(ret);
|
||
|
}
|
||
|
|
||
|
public void fieldReadInCalleeWithAngelicObjFieldMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
derefParamOk(ret.rec);
|
||
|
}
|
||
|
|
||
|
public void fieldReadInCalleeWithAngelicObjFieldMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
ret.rec.f = null;
|
||
|
derefParamOk(ret.rec);
|
||
|
}
|
||
|
|
||
|
public void accessPathOnParamOk(MyObj obj) {
|
||
|
MyObj ret = obj.rec;
|
||
|
Object f = ret.f;
|
||
|
f.toString();
|
||
|
}
|
||
|
|
||
|
public void accessPathInCalleeMayCauseFalsePositiveOk() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
accessPathOnParamOk(ret);
|
||
|
}
|
||
|
|
||
|
public void accessPathInCalleeMayCauseFalseNegativeBad() {
|
||
|
MyObj ret = externalFunc2();
|
||
|
ret.rec.f = null;
|
||
|
accessPathOnParamOk(ret);
|
||
|
}
|
||
|
|
||
|
public void skipFunctionInLoopMayCauseFalseNegativeBad() {
|
||
|
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 specInferenceMayFailAndCauseFalseNegativeBad(boolean b, Iterator<MyObj> iter) {
|
||
|
skipPointerDerefMayCauseLocalFalseNegativeBad();
|
||
|
skipPointerDerefPreventsSpecInferenceRetObj();
|
||
|
skipPointerDerefPreventsSpecInferenceRetZero();
|
||
|
skipPointerDerefMayCauseCalleeFalseNegativeBad();
|
||
|
skipPointerDerefMayCauseInterprocFalseNegativeBad();
|
||
|
castFailureOnUndefinedObjMayCauseFalseNegativeBad();
|
||
|
callOnCastUndefinedObjMayCauseFalseNegativeBad();
|
||
|
callOnUndefinedObjMayCauseFalseNegativeBad();
|
||
|
callOnUndefinedObjMayCauseFalsePositiveOk();
|
||
|
fieldWriteOnUndefinedObjMayCauseFalseNegativeBad();
|
||
|
fieldWriteOnUndefinedObjMayCauseFalsePositiveOk();
|
||
|
fieldReadOnUndefinedObjMayCauseFalseNegativeBad();
|
||
|
fieldReadOnUndefinedObjMayCauseFalsePositiveOk();
|
||
|
recursiveAngelicTypesMayCauseFalseNegativeBad();
|
||
|
recursiveAngelicTypesMayCauseFalsePositiveOk();
|
||
|
infiniteMaterializationMayCauseFalseNegativeBad(b);
|
||
|
infiniteMaterializationMayCauseFalsePositiveOk(b);
|
||
|
primitiveFieldOfAngelicObjMayCauseFalsePositiveOk();
|
||
|
primitiveFieldOfAngelicObjMayCauseFalseNegativeBad();
|
||
|
heapFieldOfAngelicObjMayCauseFalsePositiveOk();
|
||
|
heapFieldOfAngelicObjMayCauseFalseNegativeBad();
|
||
|
fieldReadAferCastMayCauseFalseNegativeBad(iter);
|
||
|
fieldReadInCalleeMayCauseFalsePositiveOk();
|
||
|
fieldReadInCalleeWithAngelicObjFieldMayCauseFalsePositiveOk();
|
||
|
accessPathInCalleeMayCauseFalsePositiveOk();
|
||
|
int i = 1 / 0;
|
||
|
}
|
||
|
}
|