From a9ff3d42a56d5605157905bada2cb3c99e056c2e Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Tue, 10 Oct 2023 04:51:24 -0700 Subject: [PATCH] [uninit][hack] Set Uninitialized attribute at sinit Summary: This diff sets `Uninitialized` attributes for all constant fields at the start of `sinit` method. Reviewed By: davidpichardie Differential Revision: D49727571 fbshipit-source-id: bb2f5fab0f9e7370ce06984cbcf0c99e6ac05d18 --- infer/src/IR/Mangled.ml | 2 +- infer/src/IR/Procname.ml | 7 +++++++ infer/src/IR/Procname.mli | 2 ++ infer/src/pulse/Pulse.ml | 27 ++++++++++++++++++++++++++- infer/src/pulse/PulseModelsHack.mli | 2 ++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/infer/src/IR/Mangled.ml b/infer/src/IR/Mangled.ml index 4dbd768fe13..d258f365adb 100644 --- a/infer/src/IR/Mangled.ml +++ b/infer/src/IR/Mangled.ml @@ -34,7 +34,7 @@ let pp f pn = F.pp_print_string f (to_string pn) let this = from_string "this" -let is_this = function {plain= "this"} -> true | _ -> false +let is_this = function {plain= "this" | "$this"} -> true | _ -> false let self = from_string "self" diff --git a/infer/src/IR/Procname.ml b/infer/src/IR/Procname.ml index e1995b8c515..600d70b2558 100644 --- a/infer/src/IR/Procname.ml +++ b/infer/src/IR/Procname.ml @@ -1188,6 +1188,13 @@ let is_hack_builtins = function false +let is_hack_sinit = function + | Hack {function_name} -> + String.equal function_name "_86sinit" + | _ -> + false + + let has_hack_classname = function Hack {class_name= Some _} -> true | _ -> false let get_global_name_of_initializer t = diff --git a/infer/src/IR/Procname.mli b/infer/src/IR/Procname.mli index e953499265c..59641bab5f4 100644 --- a/infer/src/IR/Procname.mli +++ b/infer/src/IR/Procname.mli @@ -547,6 +547,8 @@ val is_erlang_call_qualified : t -> bool val is_hack_builtins : t -> bool +val is_hack_sinit : t -> bool + val has_hack_classname : t -> bool module Normalizer : HashNormalizer.S with type t = t diff --git a/infer/src/pulse/Pulse.ml b/infer/src/pulse/Pulse.ml index ac02a2b2f70..04900b9e94f 100644 --- a/infer/src/pulse/Pulse.ml +++ b/infer/src/pulse/Pulse.ml @@ -1426,13 +1426,38 @@ let with_html_debug_node node ~desc ~f = ~f +let set_uninitialize_prop path tenv ({ProcAttributes.loc} as proc_attrs) astate = + let pname = ProcAttributes.get_proc_name proc_attrs in + if Procname.is_hack_sinit pname then + let ( let* ) x f = match x with None -> astate | Some x -> f x in + let* name = Procname.get_class_type_name pname in + let* {Struct.fields} = Tenv.lookup tenv name in + let class_global_var = PulseModelsHack.get_static_companion_var name in + let typ = Typ.mk_struct name in + List.fold fields ~init:astate ~f:(fun astate (fld, {Typ.quals= fld_quals}, _) -> + (* Ideally, we would like to analyze `abstract const` fields only, but current SIL cannot + express the `abstract` field at the moment. *) + if Typ.is_const fld_quals then + match + PulseOperations.eval path NoAccess loc (Lfield (Lvar class_global_var, fld, typ)) astate + with + | Sat (Ok (astate, (fld, _))) -> + AbductiveDomain.AddressAttributes.add_one fld (Uninitialized Const) astate + | _ -> + astate + else astate ) + else astate + + let initial tenv proc_attrs specialization = + let path = PathContext.initial in let initial_astate = AbductiveDomain.mk_initial tenv proc_attrs specialization |> PulseSummary.initial_with_positive_self proc_attrs |> PulseTaintOperations.taint_initial tenv proc_attrs + |> set_uninitialize_prop path tenv proc_attrs in - [(ContinueProgram initial_astate, PathContext.initial)] + [(ContinueProgram initial_astate, path)] let should_analyze proc_desc = diff --git a/infer/src/pulse/PulseModelsHack.mli b/infer/src/pulse/PulseModelsHack.mli index ce2eba836c0..34e3b26d78c 100644 --- a/infer/src/pulse/PulseModelsHack.mli +++ b/infer/src/pulse/PulseModelsHack.mli @@ -19,3 +19,5 @@ val get_static_companion : -> Typ.name -> PulseAbductiveDomain.t -> PulseBaseStack.value * PulseAbductiveDomain.t + +val get_static_companion_var : Typ.name -> Pvar.t