From bee713e55718e7e78035d93aa26f0237901d507e Mon Sep 17 00:00:00 2001 From: Dulma Rodriguez Date: Wed, 21 Oct 2015 05:12:10 -0700 Subject: [PATCH] Fixing mangling of captured variables Summary: public This diff fixes incorrect mangling of captured variables in blocks. Because they are formals, they shouldn't be mangled, but this case was not taken into account. This caused an assert false in the example infer/tests/codetoanalyze/objc/frontend/block/block.m which wasn't caught before because there wasn't an endtoend test for it. Reviewed By: akotulski Differential Revision: D2560379 fb-gh-sync-id: db500b6 --- infer/src/clang/cVar_decl.ml | 9 ++- .../endtoend/objc/BlockDivideByZeroTest.java | 63 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 infer/tests/endtoend/objc/BlockDivideByZeroTest.java diff --git a/infer/src/clang/cVar_decl.ml b/infer/src/clang/cVar_decl.ml index a2f403e0e..9bb33c2d5 100644 --- a/infer/src/clang/cVar_decl.ml +++ b/infer/src/clang/cVar_decl.ml @@ -18,13 +18,20 @@ module L = Logging let is_custom_var_pointer pointer = Utils.string_is_prefix CFrontend_config.pointer_prefix pointer +let is_captured procdesc vname = + IList.exists + (fun (name, _) -> (Mangled.to_string name) = vname) + (Cfg.Procdesc.get_captured procdesc) + let sil_var_of_decl context var_decl procname = let outer_procname = CContext.get_outer_procname context in + let procdesc = context.CContext.procdesc in let open Clang_ast_t in match var_decl with | VarDecl (decl_info, name_info, type_ptr, var_decl_info) -> let shoud_be_mangled = - not (is_custom_var_pointer decl_info.Clang_ast_t.di_pointer) in + not (is_custom_var_pointer decl_info.Clang_ast_t.di_pointer) && + not (is_captured procdesc name_info.Clang_ast_t.ni_name) in let var_decl_details = Some (decl_info, type_ptr, var_decl_info, shoud_be_mangled) in General_utils.mk_sil_var name_info var_decl_details procname outer_procname | ParmVarDecl (decl_info, name_info, type_ptr, var_decl_info) -> diff --git a/infer/tests/endtoend/objc/BlockDivideByZeroTest.java b/infer/tests/endtoend/objc/BlockDivideByZeroTest.java new file mode 100644 index 000000000..c66a17283 --- /dev/null +++ b/infer/tests/endtoend/objc/BlockDivideByZeroTest.java @@ -0,0 +1,63 @@ +/* +* 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.objc; + +import static org.hamcrest.MatcherAssert.assertThat; +import static utils.matchers.ResultContainsErrorInMethod.contains; +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 BlockDivideByZeroTest { + + public static final String FILE = "infer/tests/codetoanalyze/objc/frontend/block/block.m"; + + private static ImmutableList inferCmd; + + public static final String DIVIDE_BY_ZERO = "DIVIDE_BY_ZERO"; + + @ClassRule + public static DebuggableTemporaryFolder folder = + new DebuggableTemporaryFolder(); + + @BeforeClass + public static void runInfer() throws InterruptedException, IOException { + inferCmd = InferRunner.createObjCInferCommand(folder, FILE); + } + + @Test + public void whenInferRunsOnMain1ThenDivideByZeroIsFound() + throws InterruptedException, IOException, InferException { + InferResults inferResults = InferRunner.runInferObjC(inferCmd); + String[] procedures = { + "main1", + }; + assertThat( + "Results should contain the expected divide by zero", + inferResults, + containsExactly( + DIVIDE_BY_ZERO, + FILE, + procedures + ) + ); + } +}