[uninit] Filter out fields if they come from unions

Summary: We get a lot of false positives for union types as union fields are treated as separate memory locations at the moment. For now we do not treat union fields as uninitialised.

Reviewed By: mbouaziz

Differential Revision: D8277363

fbshipit-source-id: efe5b4a
master
Daiva Naudziuniene 7 years ago committed by Facebook Github Bot
parent 6fccc62b34
commit 610ed0c885

@ -364,6 +364,8 @@ module Name = struct
let is_class = function CppClass _ | JavaClass _ | ObjcClass _ -> true | _ -> false let is_class = function CppClass _ | JavaClass _ | ObjcClass _ -> true | _ -> false
let is_union = function CUnion _ -> true | _ -> false
let is_objc_protocol name = match name with ObjcProtocol _ -> true | _ -> false let is_objc_protocol name = match name with ObjcProtocol _ -> true | _ -> false
let is_same_type t1 t2 = let is_same_type t1 t2 =

@ -134,6 +134,9 @@ module Name : sig
val is_class : t -> bool val is_class : t -> bool
(** [is_class name] holds if [name] names CPP/Objc/Java class *) (** [is_class name] holds if [name] names CPP/Objc/Java class *)
val is_union : t -> bool
(** [is_union name] holds if [name] names C/CPP union *)
val is_same_type : t -> t -> bool val is_same_type : t -> t -> bool
(** [is_class name1 name2] holds if [name1] and [name2] name same kind of type *) (** [is_class name1 name2] holds if [name1] and [name2] name same kind of type *)

@ -360,7 +360,9 @@ let get_locals cfg tenv pdesc =
let pvar = Pvar.mk var_data.name (Procdesc.get_proc_name pdesc) in let pvar = Pvar.mk var_data.name (Procdesc.get_proc_name pdesc) in
let base_access_expr = AccessExpression.Base (Var.of_pvar pvar, var_data.typ) in let base_access_expr = AccessExpression.Base (Var.of_pvar pvar, var_data.typ) in
match var_data.typ.Typ.desc with match var_data.typ.Typ.desc with
| Typ.Tstruct qual_name -> ( | Typ.Tstruct qual_name
(* T30105165 remove filtering after we improve union translation *)
when not (Typ.Name.is_union qual_name) -> (
match Tenv.lookup tenv qual_name with match Tenv.lookup tenv qual_name with
| Some {fields} -> | Some {fields} ->
let flist = let flist =

@ -425,6 +425,8 @@ and get_record_typename ?tenv decl =
let args = get_template_args tenv spec_info in let args = get_template_args tenv spec_info in
let mangled = if String.equal "" mangling then None else Some mangling in let mangled = if String.equal "" mangling then None else Some mangling in
Typ.Name.Cpp.from_qual_name (Typ.Template {mangled; args}) tname Typ.Name.Cpp.from_qual_name (Typ.Template {mangled; args}) tname
| CXXRecordDecl (_, name_info, _, _, _, `TTK_Union, _, _), _ ->
Typ.CUnion (CAst_utils.get_qualified_name ~linters_mode name_info)
| CXXRecordDecl (_, name_info, _, _, _, _, _, _), _ | CXXRecordDecl (_, name_info, _, _, _, _, _, _), _
| ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _, _), _ -> | ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _, _), _ ->
(* we use Typ.CppClass for C++ because we expect Typ.CppClass from *) (* we use Typ.CppClass for C++ because we expect Typ.CppClass from *)

@ -10,7 +10,6 @@ codetoanalyze/cpp/uninit/struct.cpp, pass_basic_type_field_bad, 3, UNINITIALIZED
codetoanalyze/cpp/uninit/struct.cpp, struct_uninit_bad, 3, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/struct.cpp, struct_uninit_bad, 3, UNINITIALIZED_VALUE, no_bucket, ERROR, []
codetoanalyze/cpp/uninit/uninit.cpp, FP_no_warning_noreturn_callee_ok, 7, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/uninit.cpp, FP_no_warning_noreturn_callee_ok, 7, UNINITIALIZED_VALUE, no_bucket, ERROR, []
codetoanalyze/cpp/uninit/uninit.cpp, FP_pointer_param_void_star_ok, 4, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/uninit.cpp, FP_pointer_param_void_star_ok, 4, UNINITIALIZED_VALUE, no_bucket, ERROR, []
codetoanalyze/cpp/uninit/uninit.cpp, FP_union_ok, 6, UNINITIALIZED_VALUE, no_bucket, ERROR, []
codetoanalyze/cpp/uninit/uninit.cpp, bad1, 2, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/uninit.cpp, bad1, 2, UNINITIALIZED_VALUE, no_bucket, ERROR, []
codetoanalyze/cpp/uninit/uninit.cpp, bad2, 2, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/uninit.cpp, bad2, 2, UNINITIALIZED_VALUE, no_bucket, ERROR, []
codetoanalyze/cpp/uninit/uninit.cpp, branch1_FP, 11, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/uninit.cpp, branch1_FP, 11, UNINITIALIZED_VALUE, no_bucket, ERROR, []

@ -269,12 +269,12 @@ int* FP_pointer_param_void_star_ok() {
return a.ptr; // false positive return a.ptr; // false positive
} }
short FP_union_ok() { short union_ok() {
union { union {
int* a; int* a;
short* b; short* b;
} u; } u;
init(u.a); init(u.a);
short* p = u.b; // false positive short* p = u.b;
return *p; return *p;
} }

Loading…
Cancel
Save