From b0da1c6837dd5df8529a14830d3bc58f9d4bec17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezgi=20=C3=87i=C3=A7ek?= Date: Tue, 21 Apr 2020 09:33:32 -0700 Subject: [PATCH] [frontend][clang] Remove call to skip when translating CXXStdInitializerListExpr Summary: We translated the expression `CXXStdInitializerListExpr` naively in D3058895 as a call to a skip function, with the hope that it would be translated better in the future. However, the naive means that we lose access to the initialized list/array because we are simply skipping it. So, even if we want to model the initializer properly, we have to deal with the skip specially. This diff tries to solve this problem by removing the skip call whenever possible. Instead, we translate the underlying array/list as a Load, so that when it is passed to the constructor, we can pick it up. For the following initialization: ``` std::vector vec = {nullptr}; ``` Before, we translated it as ``` *&0$?%__sil_tmpSIL_materialize_temp__n$7[0]:int* const =null n$8=_fun___infer_skip_function(&0$?%__sil_tmpSIL_materialize_temp__n$7:int* const [1*8] const ) n$9=_fun_std::vector>::vector(&vec:std::vector>*,n$8:std::initializer_list) ``` However, this means, `n$8` would be result of something skipped which we can't reason about. Instead, we just pass the underlying initialized array now, so we get the following translation: ``` *&0$?%__sil_tmpSIL_materialize_temp__n$7[0]:int* const =null n$8=*&0$?%__sil_tmpSIL_materialize_temp__n$7:int* const [1*8] const n$9=_fun_std::vector>::vector(&vec:std::vector>*,n$8:std::initializer_list) ``` Reviewed By: jvillard Differential Revision: D21155014 fbshipit-source-id: 75850b1e6 --- infer/src/clang/cTrans.ml | 12 +++++++++--- .../cpp/shared/constructors/std_init_list.cpp.dot | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 5b1de47c8..d0e6b7976 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -3245,11 +3245,17 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s let trans_state_param = {trans_state_pri with succ_nodes= []} in let res_trans_subexpr_list = List.map ~f:(instruction trans_state_param) stmts in let params = collect_returns res_trans_subexpr_list in - let sil_fun = Exp.Const (Const.Cfun BuiltinDecl.__infer_skip_function) in let ret_id = Ident.create_fresh Ident.knormal in let ret_exp = Exp.Var ret_id in - let call_instr = Sil.Call ((ret_id, typ), sil_fun, params, sil_loc, CallFlags.default) in - let res_trans_call = mk_trans_result (ret_exp, typ) {empty_control with instrs= [call_instr]} in + let res_instr = + match params with + | [(exp, typ)] -> + Sil.Load {id= ret_id; e= exp; root_typ= typ; typ; loc= sil_loc} + | _ -> + let sil_fun = Exp.Const (Const.Cfun BuiltinDecl.__infer_skip_function) in + Sil.Call ((ret_id, typ), sil_fun, params, sil_loc, CallFlags.default) + in + let res_trans_call = mk_trans_result (ret_exp, typ) {empty_control with instrs= [res_instr]} in let all_res_trans = res_trans_subexpr_list @ [res_trans_call] in PriorityNode.compute_results_to_parent trans_state_pri sil_loc ~node_name:CXXStdInitializerListExpr stmt_info ~return:res_trans_call.return all_res_trans diff --git a/infer/tests/codetoanalyze/cpp/shared/constructors/std_init_list.cpp.dot b/infer/tests/codetoanalyze/cpp/shared/constructors/std_init_list.cpp.dot index b089cc33e..5acd8d94e 100644 --- a/infer/tests/codetoanalyze/cpp/shared/constructors/std_init_list.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/shared/constructors/std_init_list.cpp.dot @@ -7,7 +7,7 @@ digraph cfg { "main.fad58de7366495db4650cfefac2fcd61_2" [label="2: Exit main \n " color=yellow style=filled] -"main.fad58de7366495db4650cfefac2fcd61_3" [label="3: DeclStmt \n VARIABLE_DECLARED(x:X); [line 22, column 14]\n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$0:int const [5*4] const ); [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[0]:int=1 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[1]:int=2 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[2]:int=3 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[3]:int=4 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[4]:int=5 [line 22, column 20]\n n$1=_fun___infer_skip_function(&0$?%__sil_tmpSIL_materialize_temp__n$0:int const [5*4] const ) [line 22, column 20]\n n$2=_fun_X::X(&x:X*,n$1:std::initializer_list) [line 22, column 20]\n " shape="box"] +"main.fad58de7366495db4650cfefac2fcd61_3" [label="3: DeclStmt \n VARIABLE_DECLARED(x:X); [line 22, column 14]\n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$0:int const [5*4] const ); [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[0]:int=1 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[1]:int=2 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[2]:int=3 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[3]:int=4 [line 22, column 20]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0[4]:int=5 [line 22, column 20]\n n$1=*&0$?%__sil_tmpSIL_materialize_temp__n$0:int const [5*4] const [line 22, column 20]\n n$2=_fun_X::X(&x:X*,n$1:std::initializer_list) [line 22, column 20]\n " shape="box"] "main.fad58de7366495db4650cfefac2fcd61_3" -> "main.fad58de7366495db4650cfefac2fcd61_2" ;