diff --git a/infer/src/checkers/typeCheck.ml b/infer/src/checkers/typeCheck.ml index b00d2e8ce..70d23d7ce 100644 --- a/infer/src/checkers/typeCheck.ml +++ b/infer/src/checkers/typeCheck.ml @@ -313,9 +313,14 @@ let typecheck_instr ext calls_this checks (node: Cfg.Node.t) idenv get_proc_desc | None -> default | Some exp_str -> let pvar = Sil.mk_pvar (Mangled.from_string exp_str) curr_pname in - let already_in_typestate = TypeState.lookup_pvar pvar typestate <> None in - - if is_assignment && already_in_typestate + let already_defined_in_typestate = + match TypeState.lookup_pvar pvar typestate with + | Some (_, ta, _) -> + not (TypeOrigin.equal TypeOrigin.Undef (TypeAnnotation.get_origin ta)) + | None -> + false in + + if is_assignment && already_defined_in_typestate then default (* Don't overwrite pvar representing result of function call. *) else Sil.Lvar pvar, typestate end diff --git a/infer/tests/codetoanalyze/java/eradicate/NoReuseUndefFunctionValues.java b/infer/tests/codetoanalyze/java/eradicate/NoReuseUndefFunctionValues.java new file mode 100644 index 000000000..92c4ae78a --- /dev/null +++ b/infer/tests/codetoanalyze/java/eradicate/NoReuseUndefFunctionValues.java @@ -0,0 +1,34 @@ +/* +* 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.eradicate; + +import javax.annotation.Nullable; + +public class NoReuseUndefFunctionValues { + + Object mObject1; + Object mObject2; + + native Object create(); + + public NoReuseUndefFunctionValues(@Nullable Object object) { + if (object != null) { + this.mObject1 = object; + } else { + this.mObject1 = this.create(); + } + if (object != null) { + this.mObject2 = object; + } else { + this.mObject2 = this.create(); + } + } + +} diff --git a/infer/tests/endtoend/java/eradicate/NoReuseUndefFunctionValuesTest.java b/infer/tests/endtoend/java/eradicate/NoReuseUndefFunctionValuesTest.java new file mode 100644 index 000000000..62a35ffbc --- /dev/null +++ b/infer/tests/endtoend/java/eradicate/NoReuseUndefFunctionValuesTest.java @@ -0,0 +1,52 @@ +/* +* 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 endtoend.java.eradicate; + +import static org.hamcrest.MatcherAssert.assertThat; +import static utils.matchers.ResultContainsExactly.containsExactly; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; + +import utils.InferException; +import utils.InferResults; + +public class NoReuseUndefFunctionValuesTest { + + public static final String SOURCE_FILE = + "infer/tests/codetoanalyze/java/eradicate/NoReuseUndefFunctionValues.java"; + + public static final String FIELD_NOT_INITIALIZED = + "ERADICATE_FIELD_NOT_INITIALIZED"; + + private static InferResults inferResults; + + @BeforeClass + public static void loadResults() throws InterruptedException, IOException { + inferResults = + InferResults.loadEradicateResults(NoReuseUndefFunctionValuesTest.class, SOURCE_FILE); + } + + @Test + public void matchErrors() + throws IOException, InterruptedException, InferException { + String[] noMethods = {}; + assertThat( + "Results should contain " + FIELD_NOT_INITIALIZED, + inferResults, + containsExactly( + FIELD_NOT_INITIALIZED, + SOURCE_FILE, + noMethods)); + } + +}