Do not reuse Undef function values

Summary:
Change eradicate handling of complex values so that an unknown function that
has an existing mapping to Undef is treated as if there was no existing
mapping.

Without this change, joining control-flow branches where one called a function
and the other did not resulted in a mapping to Undef. Later calls to the
function would then reuse the Undef mapping.

public

Reviewed By: cristianoc

Differential Revision: D2695548

fb-gh-sync-id: ab69c47
master
Josh Berdine 9 years ago committed by facebook-github-bot-7
parent c09db829f0
commit d66261a1f4

@ -313,9 +313,14 @@ let typecheck_instr ext calls_this checks (node: Cfg.Node.t) idenv get_proc_desc
| None -> default | None -> default
| Some exp_str -> | Some exp_str ->
let pvar = Sil.mk_pvar (Mangled.from_string exp_str) curr_pname in let pvar = Sil.mk_pvar (Mangled.from_string exp_str) curr_pname in
let already_in_typestate = TypeState.lookup_pvar pvar typestate <> None in 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_in_typestate if is_assignment && already_defined_in_typestate
then default (* Don't overwrite pvar representing result of function call. *) then default (* Don't overwrite pvar representing result of function call. *)
else Sil.Lvar pvar, typestate else Sil.Lvar pvar, typestate
end end

@ -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();
}
}
}

@ -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));
}
}
Loading…
Cancel
Save