From a5c999db1e0510b783e910496f3d82bb9eff086a Mon Sep 17 00:00:00 2001 From: Josh Berdine Date: Tue, 4 Jul 2017 08:50:48 -0700 Subject: [PATCH] [threadsafety] Limited support for more access path forms Summary: The thread safety domain manipulates access paths that are a variable followed by a sequence of field or index accesses. Some expressions from C++ code do not fit that form, such as cases where subtraction of an offset from a pointer is used to obtain another pointer, whose fields are then accessed. Previously the analyzer would crash on such expressions. This diff partially treats them by introducing dummy variables. Reviewed By: da319 Differential Revision: D5343567 fbshipit-source-id: f73b520 --- infer/src/IR/HilExp.ml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/infer/src/IR/HilExp.ml b/infer/src/IR/HilExp.ml index d9df51b5a..086ab49b8 100644 --- a/infer/src/IR/HilExp.ml +++ b/infer/src/IR/HilExp.ml @@ -85,6 +85,18 @@ let rec of_sil ~f_resolve_id (exp : Exp.t) typ = match exp with AccessPath.base_of_pvar pvar typ, of_sil ~f_resolve_id value typ) closure.captured_vars in Closure (closure.name, environment) + | Lfield (root_exp, fld, root_exp_typ) -> ( + match AccessPath.of_lhs_exp exp typ ~f_resolve_id with + | Some access_path -> + AccessPath access_path + | None -> + (* unsupported field expression: represent with a dummy variable *) + of_sil ~f_resolve_id + (Exp.Lfield + (Var (Ident.create_normal (Ident.string_to_name (Exp.to_string root_exp)) 0), + fld, + root_exp_typ)) + typ ) | Lindex (Const (Cstr s), index_exp) -> (* indexed string literal (e.g., "foo"[1]). represent this by introducing a dummy variable for the string literal. if you actually need to see the value of the string literal in the @@ -92,12 +104,23 @@ let rec of_sil ~f_resolve_id (exp : Exp.t) typ = match exp with literal, e.g. using `const_cast` *) of_sil ~f_resolve_id (Exp.Lindex (Var (Ident.create_normal (Ident.string_to_name s) 0), index_exp)) typ - | Lvar _ | Lfield _ | Lindex _ -> + | Lindex (root_exp, index_exp) -> ( + match AccessPath.of_lhs_exp exp typ ~f_resolve_id with + | Some access_path -> + AccessPath access_path + | None -> + (* unsupported index expression: represent with a dummy variable *) + of_sil ~f_resolve_id + (Exp.Lindex + (Var (Ident.create_normal (Ident.string_to_name (Exp.to_string root_exp)) 0), + index_exp)) + typ ) + | Lvar _ -> match AccessPath.of_lhs_exp exp typ ~f_resolve_id with | Some access_path -> AccessPath access_path | None -> - failwithf "Couldn't convert var/field/index expression %a to access path" Exp.pp exp + failwithf "Couldn't convert var expression %a to access path" Exp.pp exp let is_null_literal = function | Constant (Cint n) -> IntLit.isnull n