From 2efa22073cbc1d335676f0d426414531224878dd Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Tue, 17 Nov 2020 11:58:15 -0800 Subject: [PATCH] [clang] force node creation in switch statements Summary: The translation of `switch` cases needs to insert nodes around the translation of each `case` sub-statement, so we need to force node creation in these sub-statements so the nodes around it can be connected to the translation of the sub-statements. Also added more logging I found useful when debugging that. Reviewed By: da319 Differential Revision: D24991455 fbshipit-source-id: d3a622142 --- infer/src/clang/SwitchCase.ml | 4 ++-- infer/src/clang/cTrans.ml | 20 ++++++++++++++----- .../cpp/liveness/dead_stores.cpp | 10 ++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/infer/src/clang/SwitchCase.ml b/infer/src/clang/SwitchCase.ml index cc6b41b85..b6b9d5583 100644 --- a/infer/src/clang/SwitchCase.ml +++ b/infer/src/clang/SwitchCase.ml @@ -26,12 +26,12 @@ let add switch_case = current_cases := switch_case :: !current_cases let pp_condition fmt = function | Case stmt -> - F.fprintf fmt "case %a:" (Pp.of_string ~f:Clang_ast_j.string_of_stmt) stmt + F.fprintf fmt "case %a:" (Pp.of_string ~f:Clang_ast_proj.get_stmt_kind_string) stmt | Default -> F.pp_print_string fmt "default:" let pp fmt {condition; root_nodes} = - F.fprintf fmt "%a -> @[[%a]@]" pp_condition condition + F.fprintf fmt "%a->@[[%a]@]" pp_condition condition (Pp.semicolon_seq Procdesc.Node.pp) root_nodes diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index c03ea2f42..e6ddbeb00 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1938,9 +1938,12 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s | _ -> assert false in - let body_trans_result = instruction trans_state body in - (let open SwitchCase in - add {condition= Case condition; stmt_info; root_nodes= body_trans_result.control.root_nodes}) ; + L.debug Capture Verbose "translating a caseStmt@\n" ; + let body_trans_result = exec_with_node_creation ~f:instruction trans_state body in + L.debug Capture Verbose "result of translating a caseStmt: %a@\n" pp_control + body_trans_result.control ; + SwitchCase.add + {condition= Case condition; stmt_info; root_nodes= body_trans_result.control.root_nodes} ; body_trans_result @@ -2013,7 +2016,11 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s let switch_cases, (_ : trans_result) = SwitchCase.in_switch_body ~f:(instruction inner_trans_state) body in - let link_up_switch_cases curr_succ_nodes = function + let link_up_switch_cases curr_succ_nodes case = + L.debug Capture Verbose "switch: curr_succ_nodes=[%a], linking case %a@\n" + (Pp.semicolon_seq Procdesc.Node.pp) + curr_succ_nodes SwitchCase.pp case ; + match (case : SwitchCase.t) with | {SwitchCase.condition= Case case_condition; stmt_info; root_nodes} -> (* create case prune nodes, link the then branch to [root_nodes], the else branch to [curr_succ_nodes] *) @@ -3894,7 +3901,10 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s (Pp.of_string ~f:Clang_ast_proj.get_stmt_kind_string) instr ) ) in - L.(debug Capture Verbose) "@]" ; + L.debug Capture Verbose + "@]@\nResult of translating statement '%a' (pointer= '%a')@\ncontrol=%a@\n" + (Pp.of_string ~f:Clang_ast_proj.get_stmt_kind_string) + instr pp_pointer instr pp_control trans_result.control ; (* don't forget to reset this so we output messages for future errors too *) logged_error := false ; trans_result diff --git a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp index 90d6aa46a..3cd12f752 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp +++ b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp @@ -599,4 +599,14 @@ void binaryConditional_bad() { int j = 42; } +X getXFromInt(int x); + +void switch_with_temporary_ok() { + int x = 44; + switch (42) { + case 0: + getXFromInt(x); + }; +} + } // namespace dead_stores