diff --git a/infer/src/checkers/uninit.ml b/infer/src/checkers/uninit.ml index 8c3703b00..1a46161cd 100644 --- a/infer/src/checkers/uninit.ml +++ b/infer/src/checkers/uninit.ml @@ -31,8 +31,18 @@ end) let intraprocedural_only = true +let blacklisted_functions = [BuiltinDecl.__set_array_length] + let is_type_pointer t = match t.Typ.desc with Typ.Tptr _ -> true | _ -> false +let is_blacklisted_function call = + match call with + | HilInstr.Direct pname -> + List.exists ~f:(fun fname -> Typ.Procname.equal pname fname) blacklisted_functions + | _ -> + false + + let exp_in_set exp vset = let _, pvars = Exp.get_vars exp in List.exists ~f:(fun pv -> D.mem (Var.of_pvar pv) vset) pvars @@ -93,13 +103,16 @@ module TransferFunctions (CFG : ProcCfg.S) = struct | Assign (((lhs_var, _), _), _, _) -> let uninit_vars = D.remove lhs_var astate.uninit_vars in {astate with uninit_vars} - | Call (_, _, actuals, _, loc) -> + | Call (_, call, actuals, _, loc) -> (* in case of intraprocedural only analysis we assume that parameters passed by reference to a function will be initialized inside that function *) let uninit_vars = List.fold ~f:(fun acc actual_exp -> match actual_exp with + | HilExp.AccessPath ((actual_var, {Typ.desc= Tarray _}), _) + when is_blacklisted_function call -> + D.remove actual_var acc | HilExp.AccessPath ((actual_var, {Typ.desc= Tptr _}), _) -> D.remove actual_var acc | HilExp.Closure (_, apl) -> diff --git a/infer/tests/codetoanalyze/objc/uninit/Makefile b/infer/tests/codetoanalyze/objc/uninit/Makefile index 108b1c258..f086d81e0 100644 --- a/infer/tests/codetoanalyze/objc/uninit/Makefile +++ b/infer/tests/codetoanalyze/objc/uninit/Makefile @@ -13,7 +13,7 @@ CLANG_OPTIONS = -x objective-c -c INFER_OPTIONS = --uninit-only --debug-exceptions --project-root $(TESTS_DIR) INFERPRINT_OPTIONS = --issues-tests -SOURCES = uninit_blocks.m +SOURCES = $(wildcard *.m) include $(TESTS_DIR)/clang.make diff --git a/infer/tests/codetoanalyze/objc/uninit/arrays.m b/infer/tests/codetoanalyze/objc/uninit/arrays.m new file mode 100644 index 000000000..8fd3675a3 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/uninit/arrays.m @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include + +int define_array_ok() { + size_t len = 10; + uint8_t a[len]; // we should not report on array definition + + return 0; +} + +int bad1() { + int a[10]; + + return a[2]; // report here as values of the array are not initialized +} + +void use_int(int); + +int bad2() { + int a[10]; + use_int(a[2]); // report here as values of the array are not initialized + + return 0; +} + +int use_array_ok() { + int a[10]; + a[1] = 5; + + return a[1]; +} + +int initialize_array_ok1() { + int arr[10]; + arr[0] = 5; +} + +int initialize_array_ok2() { + int arr[] = {1, 2}; + arr[0] = 5; +} + +void use_array(int[]); + +int pass_array_FN() { + int arr[5]; + use_array(arr); // we do not report here because of intraprocedural analysi a + // the array passed by ref +} + +int array_length_undef_bad() { + int x; + int arr[x]; +} diff --git a/infer/tests/codetoanalyze/objc/uninit/issues.exp b/infer/tests/codetoanalyze/objc/uninit/issues.exp index 58bd2b4bb..7b2a939d8 100644 --- a/infer/tests/codetoanalyze/objc/uninit/issues.exp +++ b/infer/tests/codetoanalyze/objc/uninit/issues.exp @@ -1 +1,4 @@ +codetoanalyze/objc/uninit/arrays.m, array_length_undef_bad, 2, UNINITIALIZED_VALUE, [] +codetoanalyze/objc/uninit/arrays.m, bad1, 3, UNINITIALIZED_VALUE, [] +codetoanalyze/objc/uninit/arrays.m, bad2, 2, UNINITIALIZED_VALUE, [] codetoanalyze/objc/uninit/uninit_blocks.m, A_bad1, 5, UNINITIALIZED_VALUE, []