From 59a3b9c22a3441577039e6909b731017054b3b84 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Thu, 21 Jan 2016 06:24:54 -0800 Subject: [PATCH] add temp var from compoundLiteralExpr to the function locals Summary: public otherwise Infer cannot know the type of the temporary variable Reviewed By: dulmarod Differential Revision: D2845054 fb-gh-sync-id: cf5fb8d --- infer/src/clang/cTrans.ml | 1 + .../errors/initialization/compound_literal.c | 21 +++++++ .../initialization/compound_literal.c.dot | 4 +- .../endtoend/c/CompoundLiteralExprTest.java | 59 +++++++++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 infer/tests/codetoanalyze/c/errors/initialization/compound_literal.c create mode 100644 infer/tests/endtoend/c/CompoundLiteralExprTest.java diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 332133aef..faa1610e3 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1834,6 +1834,7 @@ struct let (pvar, typ) = mk_temp_sil_var_for_expr context.CContext.tenv procdesc "SIL_compound_literal__" expr_info in let typ_ptr = Sil.Tptr (typ, Sil.Pk_pointer) in + Cfg.Procdesc.append_locals procdesc [(Sil.pvar_get_name pvar, typ)]; let var_res_trans = { empty_res_trans with exps = [(Sil.Lvar pvar, typ_ptr)] } in initListExpr_trans trans_state var_res_trans stmt_info expr_info stmt_list diff --git a/infer/tests/codetoanalyze/c/errors/initialization/compound_literal.c b/infer/tests/codetoanalyze/c/errors/initialization/compound_literal.c new file mode 100644 index 000000000..3ea4f50d2 --- /dev/null +++ b/infer/tests/codetoanalyze/c/errors/initialization/compound_literal.c @@ -0,0 +1,21 @@ +/* + * 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. + */ + +struct point { + int x; + int y; +}; + +int return_zero() { + return ((struct point) { .y = 32, .x = 0 }).x; +} + +int divide_by_zero() { + return 1/return_zero(); +} diff --git a/infer/tests/codetoanalyze/c/frontend/initialization/compound_literal.c.dot b/infer/tests/codetoanalyze/c/frontend/initialization/compound_literal.c.dot index faa7080ee..e070c8389 100644 --- a/infer/tests/codetoanalyze/c/frontend/initialization/compound_literal.c.dot +++ b/infer/tests/codetoanalyze/c/frontend/initialization/compound_literal.c.dot @@ -14,14 +14,14 @@ digraph iCFG { 4 -> 7 ; -3 [label="3: Return Stmt \n *&SIL_compound_literal__n$0.x:int =52 [line 16]\n *&SIL_compound_literal__n$0.y:int =32 [line 16]\n n$1=*&SIL_compound_literal__n$0.x:int [line 16]\n *&return:int =n$1 [line 16]\n REMOVE_TEMPS(n$1); [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] +3 [label="3: Return Stmt \n *&SIL_compound_literal__n$0.x:int =52 [line 16]\n *&SIL_compound_literal__n$0.y:int =32 [line 16]\n n$1=*&SIL_compound_literal__n$0.x:int [line 16]\n *&return:int =n$1 [line 16]\n REMOVE_TEMPS(n$1); [line 16]\n NULLIFY(&SIL_compound_literal__n$0,false); [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] 3 -> 2 ; 2 [label="2: Exit compound_literal_expr \n " color=yellow style=filled] -1 [label="1: Start compound_literal_expr\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 15]\n " color=yellow style=filled] +1 [label="1: Start compound_literal_expr\nFormals: \nLocals: SIL_compound_literal__n$0:struct point \n DECLARE_LOCALS(&return,&SIL_compound_literal__n$0); [line 15]\n " color=yellow style=filled] 1 -> 3 ; diff --git a/infer/tests/endtoend/c/CompoundLiteralExprTest.java b/infer/tests/endtoend/c/CompoundLiteralExprTest.java new file mode 100644 index 000000000..1aeba9b9d --- /dev/null +++ b/infer/tests/endtoend/c/CompoundLiteralExprTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013 - 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.c; + +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 CompoundLiteralExprTest { + + public static final String SOURCE_FILE = + "initialization/compound_literal.c"; + + public static final String DIVIDE_BY_ZERO = "DIVIDE_BY_ZERO"; + + private static InferResults inferResults; + + @BeforeClass + public static void loadResults() throws InterruptedException, IOException { + inferResults = InferResults.loadCInferResults(CompoundLiteralExprTest.class, SOURCE_FILE); + } + + @Test + public void whenInferRunsThenDivideByZeroIsFound() + throws InterruptedException, IOException, InferException { + String[] methods = { + "divide_by_zero" + }; + assertThat( + "Results should contain " + DIVIDE_BY_ZERO, + inferResults, + containsExactly( + DIVIDE_BY_ZERO, + SOURCE_FILE, + methods + ) + ); + } + +}