diff --git a/infer/src/checkers/uninit.ml b/infer/src/checkers/uninit.ml index b3e77c878..5ca5015fa 100644 --- a/infer/src/checkers/uninit.ml +++ b/infer/src/checkers/uninit.ml @@ -61,6 +61,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct let is_struct t = match t.Typ.desc with Typ.Tstruct _ -> true | _ -> false + let is_array t = match t.Typ.desc with Typ.Tarray _ -> true | _ -> false + let get_formals call = match Ondemand.get_proc_desc call with | Some proc_desc -> @@ -93,6 +95,11 @@ module TransferFunctions (CFG : ProcCfg.S) = struct && function_expects_a_pointer_as_nth_param call idx + let is_array_element_passed_by_ref call t access_expr idx = + is_array t && not (AccessExpression.is_base access_expr) + && function_expects_a_pointer_as_nth_param call idx + + let report_on_function_params call pdesc tenv uninit_vars actuals loc extras = List.iteri ~f:(fun idx e -> @@ -297,7 +304,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct match AccessExpression.get_base access_expr with | _, {Typ.desc= Tarray _} when is_blacklisted_function call -> D.remove access_expr acc - | _, t when is_struct_field_passed_by_ref call t access_expr idx -> + | _, t + when is_struct_field_passed_by_ref call t access_expr idx + || is_array_element_passed_by_ref call t access_expr idx -> (* Access to a field of a struct by reference *) if Config.uninit_interproc then remove_initialized_params pdesc call acc idx access_expr_to_remove false diff --git a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp index ea52fe274..c91587efa 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp +++ b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp @@ -169,6 +169,13 @@ int array_initialized_ok(int N, int index) { return value; } +int array_element_passed_by_ref_ok() { + int array[1]; + init(&(array[0])); + int value = array[0]; + return value; +} + int ret_undef_bad() { int* p; return *p; // report as p was not initialized