diff --git a/infer/lib/linter_rules/linters.al b/infer/lib/linter_rules/linters.al index 3a234b206..be4032c20 100644 --- a/infer/lib/linter_rules/linters.al +++ b/infer/lib/linter_rules/linters.al @@ -124,7 +124,8 @@ DEFINE-CHECKER REGISTERED_OBSERVER_BEING_DEALLOCATED = { SET report_when = WHEN - NOT (eventually_addObserver IMPLIES eventually_removeObserver) + NOT (eventually_addObserver IMPLIES eventually_removeObserver) AND + NOT iphoneos_target_sdk_version_greater_or_equal("9.0") //this is not needed after iOS SDK 9.0 HOLDS-IN-NODE ObjCImplementationDecl, ObjCProtocolDecl; SET message = diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index aab762c1c..9eed3ea46 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -505,6 +505,13 @@ let iphoneos_target_sdk_version_by_path (cxt: CLintersContext.context) = | None (* no version by path specified, use default version *) -> Config.iphoneos_target_sdk_version +let iphoneos_target_sdk_version_greater_or_equal (cxt: CLintersContext.context) version = + match iphoneos_target_sdk_version_by_path cxt with + | Some target_version + -> Utils.compare_versions target_version version >= 0 + | None + -> false + let decl_unavailable_in_supported_ios_sdk (cxt: CLintersContext.context) an = let config_iphoneos_target_sdk_version = iphoneos_target_sdk_version_by_path cxt in let allowed_os_versions = diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index 45b4d2a4d..ae60a8369 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -122,4 +122,6 @@ val has_visibility_attribute : Ctl_parser_types.ast_node -> ALVar.alexp -> bool val has_used_attribute : Ctl_parser_types.ast_node -> bool +val iphoneos_target_sdk_version_greater_or_equal : CLintersContext.context -> string -> bool + val within_available_class_block : CLintersContext.context -> Ctl_parser_types.ast_node -> bool diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index 54151df39..5e3405383 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -830,6 +830,8 @@ let rec eval_Atomic _pred_name args an lcxt = -> CPredicates.is_strong_property an | "is_unop_with_kind", [kind], an -> CPredicates.is_unop_with_kind an kind + | "iphoneos_target_sdk_version_greater_or_equal", [version], _ + -> CPredicates.iphoneos_target_sdk_version_greater_or_equal lcxt (ALVar.alexp_to_string version) | "method_return_type", [typ], an -> CPredicates.method_return_type an typ | "within_responds_to_selector_block", [], an diff --git a/infer/tests/codetoanalyze/objc/ioslints/Makefile b/infer/tests/codetoanalyze/objc/ioslints/Makefile index 658ae508d..bb7ba63d7 100644 --- a/infer/tests/codetoanalyze/objc/ioslints/Makefile +++ b/infer/tests/codetoanalyze/objc/ioslints/Makefile @@ -19,6 +19,7 @@ ANALYZER = linters INFER_OPTIONS = --no-filtering --debug-exceptions --project-root $(TESTS_DIR) \ --iphoneos-target-sdk-version 8.0 \ --iphoneos-target-sdk-version-path-regex "codetoanalyze/objc/ioslints/filter_out_unavailable_api\.m:10.0" \ +--iphoneos-target-sdk-version-path-regex "codetoanalyze/objc/ioslints/RemoveObserverInGivenSDKTest\.m:9.0" \ --no-keep-going INFERPRINT_OPTIONS = --issues-tests diff --git a/infer/tests/codetoanalyze/objc/ioslints/RemoveObserverInGivenSDKTest.m b/infer/tests/codetoanalyze/objc/ioslints/RemoveObserverInGivenSDKTest.m new file mode 100644 index 000000000..27056a9b0 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/ioslints/RemoveObserverInGivenSDKTest.m @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#import + +@interface RemoveObserverInGivenSDKTest2 : NSObject + +@property(strong) NSNotificationCenter* nc; + +@end + +@implementation RemoveObserverInGivenSDKTest2 + +- (void)foo:(NSMutableDictionary*)dict { + self.nc = [NSNotificationCenter defaultCenter]; + [self.nc addObserver:self selector:@selector(foo:) name:nil object:nil]; +} + +@end