/* * Copyright (c) 2015-present, Facebook, Inc. * * 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 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 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 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; } }