From 86294e13b279946b3e5106efd89a96339b3e62e4 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Fri, 20 Sep 2024 06:22:07 -0700 Subject: [PATCH] [preanalysis] remove dead nodes Summary: Some frontends introduce dead CFG nodes. This preanalysis removes them. This also reduces the incidence of crashes resolved by D63024067 Reviewed By: jvillard Differential Revision: D63017924 Privacy Context Container: L1208441 fbshipit-source-id: e70d0713c1df99c5eabc86c7b57fde64f44168bd --- infer/src/backend/preanal.ml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/infer/src/backend/preanal.ml b/infer/src/backend/preanal.ml index c17a9fdf503..5117ae9e21d 100644 --- a/infer/src/backend/preanal.ml +++ b/infer/src/backend/preanal.ml @@ -510,6 +510,35 @@ module InjectTraitInterfaceConstinit = struct ~f:(fun () -> inject_trait_interface_constinit tenv pdesc) end +(** pre-analysis to remove nodes unreachable from start node *) +module RemoveDeadNodes = struct + let process proc_desc = + let visited = Procdesc.NodeHashSet.create 11 in + let queue = Queue.create ~capacity:(Procdesc.size proc_desc) () in + let visit n = Procdesc.NodeHashSet.add n visited in + let enqueue n = Queue.enqueue queue n in + enqueue (Procdesc.get_start_node proc_desc) ; + let rec bfs () = + match Queue.dequeue queue with + | None -> + () + | Some n when Procdesc.NodeHashSet.mem visited n -> + bfs () + | Some n -> + visit n ; + Procdesc.Node.get_succs n @ Procdesc.Node.get_exn n |> List.iter ~f:enqueue ; + bfs () + in + bfs () ; + (* do not remove the exit/exn nodes *) + Procdesc.get_exit_node proc_desc |> visit ; + Procdesc.get_exn_sink proc_desc |> Option.iter ~f:visit ; + (* remove unvisited nodes *) + Procdesc.get_nodes proc_desc + |> List.filter ~f:(fun n -> not (Procdesc.NodeHashSet.mem visited n)) + |> List.iter ~f:(Procdesc.remove_node proc_desc) +end + let do_preanalysis tenv pdesc = if not Config.preanalysis_html then NodePrinter.print_html := false ; let proc_name = Procdesc.get_proc_name pdesc in @@ -524,5 +553,6 @@ let do_preanalysis tenv pdesc = AddAbstractionInstructions.process pdesc ; if Procname.is_java proc_name then Devirtualizer.process pdesc tenv ; NoReturn.process tenv pdesc ; + RemoveDeadNodes.process pdesc ; NodePrinter.print_html := true ; ()