From 9d8fe72213c059410e5b35c827c3bb7cba52fe51 Mon Sep 17 00:00:00 2001 From: David Pichardie Date: Fri, 3 Jul 2020 06:24:54 -0700 Subject: [PATCH] Improving tests about interface default methods (and virtual calls) Reviewed By: jvillard Differential Revision: D22015269 fbshipit-source-id: b85a3ee1d --- .../java/biabduction/DefaultInInterface.java | 27 -------- .../codetoanalyze/java/biabduction/issues.exp | 1 - .../java/pulse/DefaultInInterface.java | 67 +++++++++++++++++++ .../tests/codetoanalyze/java/pulse/issues.exp | 3 + 4 files changed, 70 insertions(+), 28 deletions(-) delete mode 100644 infer/tests/codetoanalyze/java/biabduction/DefaultInInterface.java create mode 100644 infer/tests/codetoanalyze/java/pulse/DefaultInInterface.java diff --git a/infer/tests/codetoanalyze/java/biabduction/DefaultInInterface.java b/infer/tests/codetoanalyze/java/biabduction/DefaultInInterface.java deleted file mode 100644 index 19d67180b..000000000 --- a/infer/tests/codetoanalyze/java/biabduction/DefaultInInterface.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -interface I { - default Object defaultMethod1() { - return null; - } - - default Object defaultMethod2() { - return "foo"; - } -} - -public class DefaultInInterface implements I { - - public void bad() { - System.out.println(this.defaultMethod1().toString()); - } - - public void ok() { - System.out.println(this.defaultMethod2().toString()); - } -} diff --git a/infer/tests/codetoanalyze/java/biabduction/issues.exp b/infer/tests/codetoanalyze/java/biabduction/issues.exp index 806a82fc7..3b2459e48 100644 --- a/infer/tests/codetoanalyze/java/biabduction/issues.exp +++ b/infer/tests/codetoanalyze/java/biabduction/issues.exp @@ -38,7 +38,6 @@ codetoanalyze/java/biabduction/CursorLeaks.java, codetoanalyze.java.infer.Cursor codetoanalyze/java/biabduction/CursorNPEs.java, codetoanalyze.java.infer.CursorNPEs.cursorFromContentResolverNPE(java.lang.String):void, 8, NULL_DEREFERENCE, B1, ERROR, [start of procedure cursorFromContentResolverNPE(...)] codetoanalyze/java/biabduction/CursorNPEs.java, codetoanalyze.java.infer.CursorNPEs.cursorFromDownloadManagerNPE(android.app.DownloadManager):int, 5, NULL_DEREFERENCE, B2, ERROR, [start of procedure cursorFromDownloadManagerNPE(...)] codetoanalyze/java/biabduction/CursorNPEs.java, codetoanalyze.java.infer.CursorNPEs.cursorFromMediaNPE():void, 2, NULL_DEREFERENCE, B1, ERROR, [start of procedure cursorFromMediaNPE()] -codetoanalyze/java/biabduction/DefaultInInterface.java, DefaultInInterface.bad():void, 1, NULL_DEREFERENCE, B1, ERROR, [start of procedure bad(),start of procedure defaultMethod1(),return from a call to Object I.defaultMethod1()] codetoanalyze/java/biabduction/DivideByZero.java, codetoanalyze.java.infer.DivideByZero.callDivideByZeroInterProc():int, 1, DIVIDE_BY_ZERO, no_bucket, ERROR, [start of procedure callDivideByZeroInterProc(),start of procedure divideByZeroInterProc(...)] codetoanalyze/java/biabduction/DivideByZero.java, codetoanalyze.java.infer.DivideByZero.divByZeroLocal(java.lang.String):int, 3, DIVIDE_BY_ZERO, no_bucket, ERROR, [start of procedure divByZeroLocal(...)] codetoanalyze/java/biabduction/DivideByZero.java, codetoanalyze.java.infer.DivideByZero.divideByZeroWithStaticField():int, 2, DIVIDE_BY_ZERO, no_bucket, ERROR, [start of procedure divideByZeroWithStaticField(),start of procedure setXToZero(),return from a call to void DivideByZero.setXToZero(),start of procedure divideByZeroInterProc(...)] diff --git a/infer/tests/codetoanalyze/java/pulse/DefaultInInterface.java b/infer/tests/codetoanalyze/java/pulse/DefaultInInterface.java new file mode 100644 index 000000000..fdc9cd6c3 --- /dev/null +++ b/infer/tests/codetoanalyze/java/pulse/DefaultInInterface.java @@ -0,0 +1,67 @@ +/* + * 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. + */ + +public class DefaultInInterface { + + static interface I { + default Object defaultMethod1() { + return null; + } + + default Object defaultMethod2() { + return "foo"; + } + } + + public static class A implements I { + public void defaultCallNPE() { + System.out.println(this.defaultMethod1().toString()); + } + + public void defaultCallOk() { + System.out.println(this.defaultMethod2().toString()); + } + } + + public static class B extends A { + public Object defaultMethod1() { + return "foo"; + } + + public Object defaultMethod2() { + return null; + } + + public void overridenCallOk() { + System.out.println(this.defaultMethod1().toString()); + } + + public void overridenCallNPE() { + System.out.println(this.defaultMethod2().toString()); + } + } + + static void FN_uncertainCallNPE(int i) { + A firstAthenB = new A(); + if (i > 0) { // feasible path + firstAthenB = new B(); + } + System.out.println(firstAthenB.defaultMethod1().toString()); + } + + static boolean alwaysFalse() { + return false; + } + + static void FP_uncertainCallOk(int i) { + A firstAthenB = new A(); + if (alwaysFalse()) { // unfeasible path + firstAthenB = new B(); + } + System.out.println(firstAthenB.defaultMethod2().toString()); + } +} diff --git a/infer/tests/codetoanalyze/java/pulse/issues.exp b/infer/tests/codetoanalyze/java/pulse/issues.exp index 13bce5bf0..56a49b69c 100644 --- a/infer/tests/codetoanalyze/java/pulse/issues.exp +++ b/infer/tests/codetoanalyze/java/pulse/issues.exp @@ -1,3 +1,6 @@ +codetoanalyze/java/pulse/DefaultInInterface.java, DefaultInInterface$A.defaultCallNPE():void, 1, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,when calling `Object DefaultInInterface$I.defaultMethod1()` here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,passed as argument to `Object DefaultInInterface$I.defaultMethod1()`,return from call to `Object DefaultInInterface$I.defaultMethod1()`,assigned,invalid access occurs here] +codetoanalyze/java/pulse/DefaultInInterface.java, DefaultInInterface$B.overridenCallNPE():void, 1, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,when calling `Object DefaultInInterface$B.defaultMethod2()` here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,passed as argument to `Object DefaultInInterface$B.defaultMethod2()`,return from call to `Object DefaultInInterface$B.defaultMethod2()`,assigned,invalid access occurs here] +codetoanalyze/java/pulse/DefaultInInterface.java, DefaultInInterface.FP_uncertainCallOk(int):void, 5, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,when calling `Object DefaultInInterface$B.defaultMethod2()` here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,passed as argument to `Object DefaultInInterface$B.defaultMethod2()`,return from call to `Object DefaultInInterface$B.defaultMethod2()`,assigned,invalid access occurs here] codetoanalyze/java/pulse/DynamicDispatch.java, codetoanalyze.java.infer.DynamicDispatch$WithField.dispatchOnFieldOK_FP():void, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,when calling `Object DynamicDispatch$Supertype.bar()` here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,passed as argument to `Object DynamicDispatch$Supertype.bar()`,return from call to `Object DynamicDispatch$Supertype.bar()`,assigned,invalid access occurs here] codetoanalyze/java/pulse/DynamicDispatch.java, codetoanalyze.java.infer.DynamicDispatch.dynamicDispatchCallsWrapperWithSubtypeOK_FP():void, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,when calling `Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)` here,when calling `Object DynamicDispatch$Supertype.bar()` here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,passed as argument to `Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)`,return from call to `Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)`,assigned,invalid access occurs here] codetoanalyze/java/pulse/DynamicDispatch.java, codetoanalyze.java.infer.DynamicDispatch.dynamicDispatchCallsWrapperWithSupertypeBad():void, 3, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,when calling `Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)` here,when calling `Object DynamicDispatch$Supertype.bar()` here,assigned,is the null pointer,use-after-lifetime part of the trace starts here,passed as argument to `Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)`,return from call to `Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)`,assigned,invalid access occurs here]