diff --git a/infer/tests/build_systems/ant/issues.exp b/infer/tests/build_systems/ant/issues.exp index 008e171a2..9339a4b69 100644 --- a/infer/tests/build_systems/ant/issues.exp +++ b/infer/tests/build_systems/ant/issues.exp @@ -22,7 +22,10 @@ codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.getBucketCountNotClos codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.getImageCountHelperNotClosed(String), 13, RESOURCE_LEAK, [start of procedure getImageCountHelperNotClosed(...),Taking true branch] codetoanalyze/java/infer/CursorLeaks.java, void CursorLeaks.loadPrefsFromContentProviderNotClosed(), 11, RESOURCE_LEAK, [start of procedure loadPrefsFromContentProviderNotClosed(),Taking false branch,Taking true branch] codetoanalyze/java/infer/CursorLeaks.java, void CursorLeaks.queryUVMLegacyDbNotClosed(), 4, RESOURCE_LEAK, [start of procedure queryUVMLegacyDbNotClosed(),Taking true branch] +codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchCallsWrapperWithSubtypeBad(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchCallsWrapperWithSubtypeBad(),start of procedure DynamicDispatch$Subtype(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),return from a call to DynamicDispatch$Subtype.(),start of procedure dynamicDispatchWrapperFoo(...),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo(),return from a call to Object DynamicDispatch.dynamicDispatchWrapperFoo(DynamicDispatch$Subtype)] +codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchCallsWrapperWithSupertypeBad(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchCallsWrapperWithSupertypeBad(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),start of procedure dynamicDispatchWrapperBar(...),start of procedure bar(),return from a call to Object DynamicDispatch$Supertype.bar(),return from a call to Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)] codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchShouldNotCauseFalseNegativeEasy(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchShouldNotCauseFalseNegativeEasy(),start of procedure DynamicDispatch$Subtype(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),return from a call to DynamicDispatch$Subtype.(),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo()] +codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchShouldNotReportWhenCallingSupertype(DynamicDispatch$Subtype), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchShouldNotReportWhenCallingSupertype(...),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo()] codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.interfaceShouldNotCauseFalseNegativeEasy(), 3, NULL_DEREFERENCE, [start of procedure interfaceShouldNotCauseFalseNegativeEasy(),start of procedure DynamicDispatch$Impl(),return from a call to DynamicDispatch$Impl.(),start of procedure foo(),return from a call to Object DynamicDispatch$Impl.foo()] codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.interfaceShouldNotCauseFalseNegativeHard(DynamicDispatch$Impl), 1, NULL_DEREFERENCE, [start of procedure interfaceShouldNotCauseFalseNegativeHard(...),start of procedure foo(),return from a call to Object DynamicDispatch$Impl.foo()] codetoanalyze/java/infer/FilterInputStreamLeaks.java, void FilterInputStreamLeaks.bufferedInputStreamNotClosedAfterRead(), 7, RESOURCE_LEAK, [start of procedure bufferedInputStreamNotClosedAfterRead(),exception java.io.IOException] diff --git a/infer/tests/build_systems/buck/issues.exp b/infer/tests/build_systems/buck/issues.exp index ddea57a9a..4e90894cd 100644 --- a/infer/tests/build_systems/buck/issues.exp +++ b/infer/tests/build_systems/buck/issues.exp @@ -22,7 +22,10 @@ infer/tests/codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.getBucket infer/tests/codetoanalyze/java/infer/CursorLeaks.java, int CursorLeaks.getImageCountHelperNotClosed(String), 13, RESOURCE_LEAK, [start of procedure getImageCountHelperNotClosed(...),Taking true branch] infer/tests/codetoanalyze/java/infer/CursorLeaks.java, void CursorLeaks.loadPrefsFromContentProviderNotClosed(), 11, RESOURCE_LEAK, [start of procedure loadPrefsFromContentProviderNotClosed(),Taking false branch,Taking true branch] infer/tests/codetoanalyze/java/infer/CursorLeaks.java, void CursorLeaks.queryUVMLegacyDbNotClosed(), 4, RESOURCE_LEAK, [start of procedure queryUVMLegacyDbNotClosed(),Taking true branch] +infer/tests/codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchCallsWrapperWithSubtypeBad(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchCallsWrapperWithSubtypeBad(),start of procedure DynamicDispatch$Subtype(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),return from a call to DynamicDispatch$Subtype.(),start of procedure dynamicDispatchWrapperFoo(...),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo(),return from a call to Object DynamicDispatch.dynamicDispatchWrapperFoo(DynamicDispatch$Subtype)] +infer/tests/codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchCallsWrapperWithSupertypeBad(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchCallsWrapperWithSupertypeBad(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),start of procedure dynamicDispatchWrapperBar(...),start of procedure bar(),return from a call to Object DynamicDispatch$Supertype.bar(),return from a call to Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)] infer/tests/codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchShouldNotCauseFalseNegativeEasy(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchShouldNotCauseFalseNegativeEasy(),start of procedure DynamicDispatch$Subtype(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),return from a call to DynamicDispatch$Subtype.(),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo()] +infer/tests/codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchShouldNotReportWhenCallingSupertype(DynamicDispatch$Subtype), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchShouldNotReportWhenCallingSupertype(...),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo()] infer/tests/codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.interfaceShouldNotCauseFalseNegativeEasy(), 3, NULL_DEREFERENCE, [start of procedure interfaceShouldNotCauseFalseNegativeEasy(),start of procedure DynamicDispatch$Impl(),return from a call to DynamicDispatch$Impl.(),start of procedure foo(),return from a call to Object DynamicDispatch$Impl.foo()] infer/tests/codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.interfaceShouldNotCauseFalseNegativeHard(DynamicDispatch$Impl), 1, NULL_DEREFERENCE, [start of procedure interfaceShouldNotCauseFalseNegativeHard(...),start of procedure foo(),return from a call to Object DynamicDispatch$Impl.foo()] infer/tests/codetoanalyze/java/infer/FilterInputStreamLeaks.java, void FilterInputStreamLeaks.bufferedInputStreamNotClosedAfterRead(), 7, RESOURCE_LEAK, [start of procedure bufferedInputStreamNotClosedAfterRead(),exception java.io.IOException] diff --git a/infer/tests/codetoanalyze/java/infer/DynamicDispatch.java b/infer/tests/codetoanalyze/java/infer/DynamicDispatch.java index 077bf78bd..714391447 100644 --- a/infer/tests/codetoanalyze/java/infer/DynamicDispatch.java +++ b/infer/tests/codetoanalyze/java/infer/DynamicDispatch.java @@ -67,10 +67,48 @@ public class DynamicDispatch { o.bar().toString(); } - // TODO: this test currently fails, but will pass with handling of dynamic dispatch - static void dynamicDispatchShouldNotCauseFalseNegativeHardTODO(Supertype o) { - // should report a warning because Subtype's implementation of foo() can return null; + static void dynamicDispatchShouldNotReportWhenCallingSupertype(Supertype o) { + // should not report a warning because the Supertype implementation + // of foo() does not return null o.foo().toString(); } + static void dynamicDispatchShouldReportWhenCalledWithSubtypeParameter(Subtype o) { + // should report a warning because the Subtype implementation + // of foo() returns null + dynamicDispatchShouldNotReportWhenCallingSupertype(o); + } + + static Object dynamicDispatchWrapperFoo(Supertype o) { + return o.foo(); + } + + static Object dynamicDispatchWrapperBar(Supertype o) { + return o.bar(); + } + + static void dynamicDispatchCallsWrapperWithSupertypeOkay() { + // Should not report because Supertype.foo() does not return null + Supertype o = new Supertype(); + dynamicDispatchWrapperFoo(o).toString(); + } + + static void dynamicDispatchCallsWrapperWithSupertypeBad() { + // Should report because Supertype.bar() returns null + Supertype o = new Supertype(); + dynamicDispatchWrapperBar(o).toString(); + } + + static void dynamicDispatchCallsWrapperWithSubtypeBad() { + // Should report because Subtype.foo() returns null + Supertype o = new Subtype(); + dynamicDispatchWrapperFoo(o).toString(); + } + + static void dynamicDispatchCallsWrapperWithSubtypeOkay() { + // Should not report because Subtype.bar() does not returns null + Supertype o = new Subtype(); + dynamicDispatchWrapperBar(o).toString(); + } + } diff --git a/infer/tests/codetoanalyze/java/infer/issues.exp b/infer/tests/codetoanalyze/java/infer/issues.exp index fa2de3f48..8f062d82b 100644 --- a/infer/tests/codetoanalyze/java/infer/issues.exp +++ b/infer/tests/codetoanalyze/java/infer/issues.exp @@ -49,7 +49,10 @@ codetoanalyze/java/infer/CursorLeaks.java, void CursorLeaks.queryUVMLegacyDbNotC codetoanalyze/java/infer/DivideByZero.java, int DivideByZero.callDivideByZeroInterProc(), 1, DIVIDE_BY_ZERO, [start of procedure callDivideByZeroInterProc(),start of procedure divideByZeroInterProc(...)] codetoanalyze/java/infer/DivideByZero.java, int DivideByZero.divByZeroLocal(String), 3, DIVIDE_BY_ZERO, [start of procedure divByZeroLocal(...)] codetoanalyze/java/infer/DivideByZero.java, int DivideByZero.divideByZeroWithStaticField(), 2, DIVIDE_BY_ZERO, [start of procedure divideByZeroWithStaticField(),start of procedure setXToZero(),return from a call to void DivideByZero.setXToZero(),start of procedure divideByZeroInterProc(...)] +codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchCallsWrapperWithSubtypeBad(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchCallsWrapperWithSubtypeBad(),start of procedure DynamicDispatch$Subtype(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),return from a call to DynamicDispatch$Subtype.(),start of procedure dynamicDispatchWrapperFoo(...),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo(),return from a call to Object DynamicDispatch.dynamicDispatchWrapperFoo(DynamicDispatch$Subtype)] +codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchCallsWrapperWithSupertypeBad(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchCallsWrapperWithSupertypeBad(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),start of procedure dynamicDispatchWrapperBar(...),start of procedure bar(),return from a call to Object DynamicDispatch$Supertype.bar(),return from a call to Object DynamicDispatch.dynamicDispatchWrapperBar(DynamicDispatch$Supertype)] codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchShouldNotCauseFalseNegativeEasy(), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchShouldNotCauseFalseNegativeEasy(),start of procedure DynamicDispatch$Subtype(),start of procedure DynamicDispatch$Supertype(),return from a call to DynamicDispatch$Supertype.(),return from a call to DynamicDispatch$Subtype.(),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo()] +codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.dynamicDispatchShouldNotReportWhenCallingSupertype(DynamicDispatch$Subtype), 3, NULL_DEREFERENCE, [start of procedure dynamicDispatchShouldNotReportWhenCallingSupertype(...),start of procedure foo(),return from a call to Object DynamicDispatch$Subtype.foo()] codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.interfaceShouldNotCauseFalseNegativeEasy(), 3, NULL_DEREFERENCE, [start of procedure interfaceShouldNotCauseFalseNegativeEasy(),start of procedure DynamicDispatch$Impl(),return from a call to DynamicDispatch$Impl.(),start of procedure foo(),return from a call to Object DynamicDispatch$Impl.foo()] codetoanalyze/java/infer/DynamicDispatch.java, void DynamicDispatch.interfaceShouldNotCauseFalseNegativeHard(DynamicDispatch$Impl), 1, NULL_DEREFERENCE, [start of procedure interfaceShouldNotCauseFalseNegativeHard(...),start of procedure foo(),return from a call to Object DynamicDispatch$Impl.foo()] codetoanalyze/java/infer/FilterInputStreamLeaks.java, void FilterInputStreamLeaks.bufferedInputStreamClosedAfterReset(), 9, NULL_TEST_AFTER_DEREFERENCE, [start of procedure bufferedInputStreamClosedAfterReset(),exception java.io.IOException,Switch condition is true. Entering switch case,Taking false branch]