diff --git a/infer/src/IR/Ident.re b/infer/src/IR/Ident.re index e9abcfab7..ac5e51946 100644 --- a/infer/src/IR/Ident.re +++ b/infer/src/IR/Ident.re @@ -66,9 +66,8 @@ let compare i1 i2 => { } }; -let equal i1 i2 => - i1.stamp === i2.stamp && i1.kind === i2.kind && name_equal i1.name i2.name - /* most unlikely first */; +let equal i1 i2 => i1.stamp === i2.stamp && i1.kind === i2.kind && name_equal i1.name i2.name +/* most unlikely first */; let fieldname_equal fn1 fn2 => fieldname_compare fn1 fn2 == 0; @@ -148,6 +147,9 @@ let name_to_string (name: name) => name; /** Convert a fieldname to a string. */ let fieldname_to_string fn => Mangled.to_string fn.fname; +/** Convert a fieldname to a string, including the mangled part. */ +let fieldname_to_complete_string fn => Mangled.to_string_full fn.fname; + /** Convert a fieldname to a simplified string with at most one-level path. */ let fieldname_to_simplified_string fn => { diff --git a/infer/src/IR/Ident.rei b/infer/src/IR/Ident.rei index 47deb6d8d..f40ccf795 100644 --- a/infer/src/IR/Ident.rei +++ b/infer/src/IR/Ident.rei @@ -105,6 +105,9 @@ let name_to_string: name => string; /** Convert a field name to a string. */ let fieldname_to_string: fieldname => string; +/** Convert a fieldname to a string, including the mangled part. */ +let fieldname_to_complete_string: fieldname => string; + /** Convert a fieldname to a simplified string with at most one-level path. */ let fieldname_to_simplified_string: fieldname => string; diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml index ddc75c8e3..46387ceb3 100644 --- a/infer/src/backend/errdesc.ml +++ b/infer/src/backend/errdesc.ml @@ -15,11 +15,13 @@ open! Utils module L = Logging module F = Format -let pointer_wrapper_classes = [ +let smart_pointers = [ ["std"; "shared_ptr"]; ["std"; "unique_ptr"] ] +let pointer_wrapper_classes = smart_pointers + let vector_class = ["std"; "vector"] let is_one_of_classes class_name classes = @@ -788,6 +790,12 @@ let explain_dereference_access outermost_array is_nullable _de_opt prop = | Some de -> Some (if outermost_array then remove_outermost_array_access de else de) in let value_str = match de_opt with + | Some (Sil.Darrow ((Sil.Dpvaraddr pvar), f) as de) -> + let complete_fieldname = Ident.fieldname_to_complete_string f in + if is_one_of_classes complete_fieldname smart_pointers && + Utils.string_contains "data" complete_fieldname then + Sil.dexp_to_string (Sil.Dpvaraddr pvar) + else Sil.dexp_to_string de | Some de -> Sil.dexp_to_string de | None -> "" in