From b95c4e34d64ab37deb9eb387be0d0cbfeb0f54ba Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Thu, 26 Oct 2017 05:29:33 -0700 Subject: [PATCH] [dead store objc] Whitelisting macro variables in dead stored checker for Objective-C Reviewed By: sblackshear Differential Revision: D6135723 fbshipit-source-id: e703345 --- Makefile | 2 +- infer/src/checkers/liveness.ml | 11 ++++- .../codetoanalyze/objc/liveness/Makefile | 19 ++++++++ .../objc/liveness/NSParameterAssertExample.m | 47 +++++++++++++++++++ .../codetoanalyze/objc/liveness/issues.exp | 0 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 infer/tests/codetoanalyze/objc/liveness/Makefile create mode 100644 infer/tests/codetoanalyze/objc/liveness/NSParameterAssertExample.m create mode 100644 infer/tests/codetoanalyze/objc/liveness/issues.exp diff --git a/Makefile b/Makefile index 8bb65985e..afba70699 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ BUILD_SYSTEMS_TESTS += xcodebuild_no_xcpretty objc_getters_setters DIRECT_TESTS += \ objc_frontend objc_errors objc_linters objc_ioslints \ objcpp_frontend objcpp_linters objc_linters-for-test-only objcpp_linters-for-test-only \ - objc_linters-def-folder objc_checkers + objc_linters-def-folder objc_checkers objc_liveness ifneq ($(XCPRETTY),no) BUILD_SYSTEMS_TESTS += xcodebuild endif diff --git a/infer/src/checkers/liveness.ml b/infer/src/checkers/liveness.ml index c184108cf..f3b70edf5 100644 --- a/infer/src/checkers/liveness.ml +++ b/infer/src/checkers/liveness.ml @@ -61,6 +61,13 @@ end module CFG = ProcCfg.OneInstrPerNode (ProcCfg.Backward (ProcCfg.Exceptional)) module Analyzer = AbstractInterpreter.Make (CFG) (TransferFunctions) +let is_whitelisted_var var = + let whitelisted_vars = ["__assert_file__"; "__assert_fn__"] in + List.exists + ~f:(fun whitelisted_var -> String.equal whitelisted_var (Pvar.get_simplified_name var)) + whitelisted_vars + + let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = let cfg = CFG.from_pdesc proc_desc in let invariant_map = @@ -83,7 +90,8 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = | Sil.Store (Lvar pvar, _, _, loc) when not ( Pvar.is_frontend_tmp pvar || Pvar.is_return pvar || Pvar.is_global pvar - || Domain.mem (Var.of_pvar pvar) live_vars || is_captured_var pvar ) -> + || Domain.mem (Var.of_pvar pvar) live_vars || is_captured_var pvar + || is_whitelisted_var pvar ) -> let issue_id = IssueType.dead_store.unique_id in let message = F.asprintf "The value written to %a is never used" (Pvar.pp Pp.text) pvar in let ltr = [Errlog.make_trace_element 0 loc "Write of unused value" []] in @@ -106,4 +114,3 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = in List.iter (CFG.nodes cfg) ~f:report_on_node ; summary - diff --git a/infer/tests/codetoanalyze/objc/liveness/Makefile b/infer/tests/codetoanalyze/objc/liveness/Makefile new file mode 100644 index 000000000..9ace83b1f --- /dev/null +++ b/infer/tests/codetoanalyze/objc/liveness/Makefile @@ -0,0 +1,19 @@ +# Copyright (c) 2016 - 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. + +TESTS_DIR = ../../.. + +ANALYZER = checkers +CLANG_OPTIONS = -x objective-c -c +INFER_OPTIONS = --liveness-only --debug-exceptions --project-root $(TESTS_DIR) +INFERPRINT_OPTIONS = --issues-tests + +SOURCES = $(wildcard *.m) + +include $(TESTS_DIR)/clang.make + +infer-out/report.json: $(MAKEFILE_LIST) diff --git a/infer/tests/codetoanalyze/objc/liveness/NSParameterAssertExample.m b/infer/tests/codetoanalyze/objc/liveness/NSParameterAssertExample.m new file mode 100644 index 000000000..1b2f1cda9 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/liveness/NSParameterAssertExample.m @@ -0,0 +1,47 @@ +/* + * 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. + */ +#import + +@interface A : NSObject +@end + +@implementation A + ++ (void)foo { + if (!(1)) { + NSString* __assert_fn__ = + [NSString stringWithUTF8String:__PRETTY_FUNCTION__]; + __assert_fn__ = __assert_fn__ ? __assert_fn__ : @""; + NSString* __assert_file__ = [NSString stringWithUTF8String:"A.m"]; + __assert_file__ = __assert_file__ ? __assert_file__ : @""; + [[NSAssertionHandler currentHandler] + handleFailureInFunction:__assert_fn__ + file:__assert_file__ + lineNumber:23 + description:(@"Hello")]; + } +} + ++ (void)bar { + int phoneNumberError = 5; + int PhoneNumberNoError = 10; + if (!((phoneNumberError != PhoneNumberNoError))) { + NSString* __assert_file__ = [NSString stringWithUTF8String:"A.m"]; + __assert_file__ = __assert_file__ ? __assert_file__ : @""; + [[NSAssertionHandler currentHandler] + handleFailureInMethod:_cmd + object:self + file:__assert_file__ + lineNumber:12 + description:(@"Invalid parameter not satisfying: %@"), + @"phoneNumberError != PhoneNumberNoError"]; + } +} + +@end diff --git a/infer/tests/codetoanalyze/objc/liveness/issues.exp b/infer/tests/codetoanalyze/objc/liveness/issues.exp new file mode 100644 index 000000000..e69de29bb