From 610ed0c8852a4b79343e0a50dcd94123d944b979 Mon Sep 17 00:00:00 2001 From: Daiva Naudziuniene Date: Wed, 6 Jun 2018 03:24:42 -0700 Subject: [PATCH] [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 --- infer/src/IR/Typ.ml | 2 ++ infer/src/IR/Typ.mli | 3 +++ infer/src/checkers/uninit.ml | 4 +++- infer/src/clang/CType_decl.ml | 2 ++ infer/tests/codetoanalyze/cpp/uninit/issues.exp | 1 - infer/tests/codetoanalyze/cpp/uninit/uninit.cpp | 4 ++-- 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/infer/src/IR/Typ.ml b/infer/src/IR/Typ.ml index 44a9c8068..68bb8c5df 100644 --- a/infer/src/IR/Typ.ml +++ b/infer/src/IR/Typ.ml @@ -364,6 +364,8 @@ module Name = struct 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_same_type t1 t2 = diff --git a/infer/src/IR/Typ.mli b/infer/src/IR/Typ.mli index a076b6aaa..e99e61f7e 100644 --- a/infer/src/IR/Typ.mli +++ b/infer/src/IR/Typ.mli @@ -134,6 +134,9 @@ module Name : sig val is_class : t -> bool (** [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 (** [is_class name1 name2] holds if [name1] and [name2] name same kind of type *) diff --git a/infer/src/checkers/uninit.ml b/infer/src/checkers/uninit.ml index e1649d838..486ea5572 100644 --- a/infer/src/checkers/uninit.ml +++ b/infer/src/checkers/uninit.ml @@ -360,7 +360,9 @@ let get_locals cfg tenv pdesc = 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 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 | Some {fields} -> let flist = diff --git a/infer/src/clang/CType_decl.ml b/infer/src/clang/CType_decl.ml index 938e10e2c..8e07177da 100644 --- a/infer/src/clang/CType_decl.ml +++ b/infer/src/clang/CType_decl.ml @@ -425,6 +425,8 @@ and get_record_typename ?tenv decl = let args = get_template_args tenv spec_info in let mangled = if String.equal "" mangling then None else Some mangling in 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, _, _, _, _, _, _), _ | ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _, _), _ -> (* we use Typ.CppClass for C++ because we expect Typ.CppClass from *) diff --git a/infer/tests/codetoanalyze/cpp/uninit/issues.exp b/infer/tests/codetoanalyze/cpp/uninit/issues.exp index 87ee2eeff..5846f3b38 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/issues.exp +++ b/infer/tests/codetoanalyze/cpp/uninit/issues.exp @@ -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/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_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, bad2, 2, UNINITIALIZED_VALUE, no_bucket, ERROR, [] codetoanalyze/cpp/uninit/uninit.cpp, branch1_FP, 11, UNINITIALIZED_VALUE, no_bucket, ERROR, [] diff --git a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp index 6f0f649b7..046fc9eb0 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp +++ b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp @@ -269,12 +269,12 @@ int* FP_pointer_param_void_star_ok() { return a.ptr; // false positive } -short FP_union_ok() { +short union_ok() { union { int* a; short* b; } u; init(u.a); - short* p = u.b; // false positive + short* p = u.b; return *p; }