From c0e53654583eb523ad2f59898c951aa1608ffd8a Mon Sep 17 00:00:00 2001 From: Dulma Rodriguez Date: Thu, 24 Mar 2016 10:20:40 -0700 Subject: [PATCH] Translate delete of arrays with the correct destructor Reviewed By: ddino Differential Revision: D3093264 fb-gh-sync-id: 036e27e shipit-source-id: 036e27e --- infer/src/clang/cTrans.ml | 7 ++- .../cpp/errors/memory_leaks/array_leak.cpp | 25 ++++++++ .../endtoend/cpp/MemoryLeakArrayTest.java | 62 +++++++++++++++++++ 3 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 infer/tests/codetoanalyze/cpp/errors/memory_leaks/array_leak.cpp create mode 100644 infer/tests/endtoend/cpp/MemoryLeakArrayTest.java diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 0575ab1e3..63a1bb52e 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1964,13 +1964,14 @@ struct let result_trans_to_parent = PriorityNode.compute_results_to_parent trans_state_pri sil_loc nname stmt_info all_res_trans in { result_trans_to_parent with exps = res_trans_new.exps } - (* TODOs 7912220 - no usable information in json as of right now *) - (* 1. Handle __new_array *) and cxxDeleteExpr_trans trans_state stmt_info stmt_list delete_expr_info = let context = trans_state.context in let sil_loc = CLocation.get_sil_location stmt_info context in - let fname = SymExec.ModelBuiltins.__delete in + let is_array = delete_expr_info.Clang_ast_t.xdei_is_array in + let fname = + if is_array then SymExec.ModelBuiltins.__delete_array + else SymExec.ModelBuiltins.__delete in let param = match stmt_list with [p] -> p | _ -> assert false in let trans_state_pri = PriorityNode.try_claim_priority_node trans_state stmt_info in let trans_state_param = { trans_state_pri with succ_nodes = [] } in diff --git a/infer/tests/codetoanalyze/cpp/errors/memory_leaks/array_leak.cpp b/infer/tests/codetoanalyze/cpp/errors/memory_leaks/array_leak.cpp new file mode 100644 index 000000000..51250f478 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/errors/memory_leaks/array_leak.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 - 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. + */ + +int no_leak() { + int* arr = new int[5]; + arr[0] = 1; + arr[1] = 2; + int res = arr[0] + arr[1]; + delete[] arr; + return res; +} + +int leak() { + int* arr = new int[5]; + arr[0] = 1; + arr[1] = 2; + int res = arr[0] + arr[1]; + return res; +} diff --git a/infer/tests/endtoend/cpp/MemoryLeakArrayTest.java b/infer/tests/endtoend/cpp/MemoryLeakArrayTest.java new file mode 100644 index 000000000..5577e951a --- /dev/null +++ b/infer/tests/endtoend/cpp/MemoryLeakArrayTest.java @@ -0,0 +1,62 @@ +/* + * 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.cpp; + +import static org.hamcrest.MatcherAssert.assertThat; +import static utils.matchers.ResultContainsExactly.containsExactly; + +import com.google.common.collect.ImmutableList; + +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +import java.io.IOException; + +import utils.DebuggableTemporaryFolder; +import utils.InferException; +import utils.InferResults; +import utils.InferRunner; + +public class MemoryLeakArrayTest { + + public static final String FILE = + "infer/tests/codetoanalyze/cpp/errors/memory_leaks/array_leak.cpp"; + + private static ImmutableList inferCmd; + + public static final String MEMORY_LEAK = "MEMORY_LEAK"; + + @ClassRule + public static DebuggableTemporaryFolder folder = + new DebuggableTemporaryFolder(); + + @BeforeClass + public static void runInfer() throws InterruptedException, IOException { + inferCmd = InferRunner.createCPPInferCommandWithMLBuckets(folder, FILE, "cpp"); + } + + @Test + public void whenInferRunsOnObject_leakThenMLIsFound() + throws InterruptedException, IOException, InferException { + InferResults inferResults = InferRunner.runInferCPP(inferCmd); + String[] methods = { "leak" }; + assertThat( + "Results should contain " + MEMORY_LEAK, + inferResults, + containsExactly( + MEMORY_LEAK, + FILE, + methods + ) + ); + } + +}