diff --git a/infer/src/backend/RetainCycles.ml b/infer/src/backend/RetainCycles.ml index 162ec55b5..63ec246f9 100644 --- a/infer/src/backend/RetainCycles.ml +++ b/infer/src/backend/RetainCycles.ml @@ -63,11 +63,11 @@ let edge_is_strong tenv obj_edge = let find fields = List.find ~f:equal_fn fields |> Option.value_map ~f:trd3 ~default:[] in - find fields @ find statics + Some (find fields @ find statics) | None -> - [] ) + None ) | _ -> - [] + None in let has_weak_or_unretained_or_assign params = List.exists @@ -76,14 +76,18 @@ let edge_is_strong tenv obj_edge = || String.equal Config.assign att ) params in - let ia = get_item_annotation obj_edge.rc_from.rc_node_typ obj_edge.rc_field.rc_field_name in let weak_edge = - List.exists - ~f:(fun ((ann: Annot.t), _) -> - ( String.equal ann.class_name Config.property_attributes - || String.equal ann.class_name Config.ivar_attributes ) - && has_weak_or_unretained_or_assign ann.parameters ) - ia + match get_item_annotation obj_edge.rc_from.rc_node_typ obj_edge.rc_field.rc_field_name with + | Some ia -> + List.exists + ~f:(fun ((ann: Annot.t), _) -> + ( String.equal ann.class_name Config.property_attributes + || String.equal ann.class_name Config.ivar_attributes ) + && has_weak_or_unretained_or_assign ann.parameters ) + ia + | None -> + true + (* Assume the edge is weak if the type cannot be found in the tenv, to avoid FPs *) in not weak_edge diff --git a/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/Caller.m b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/Caller.m new file mode 100644 index 000000000..5e664837f --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/Caller.m @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018 - 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 "ViewController.h" +#import + +int main() { + ViewController* controller = [ViewController new]; + return 0; +} diff --git a/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/View.h b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/View.h new file mode 100644 index 000000000..7c63bc176 --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/View.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018 - 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 View : NSObject + +@property(nonatomic, weak) id delegate; + +@end diff --git a/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/View.m b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/View.m new file mode 100644 index 000000000..6d926fc32 --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/View.m @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018 - 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 "View.h" + +@implementation View + +@end diff --git a/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/ViewController.h b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/ViewController.h new file mode 100644 index 000000000..0c3b1e926 --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/ViewController.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018 - 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 ViewController : NSObject + +@end diff --git a/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/ViewController.m b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/ViewController.m new file mode 100644 index 000000000..f3eb0771c --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/objc_retain_cycles/ViewController.m @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 - 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 "ViewController.h" + +@implementation ViewController { + View* _hostingView; +} + +- (instancetype)init { + if (self = [super init]) { + _hostingView = [[View alloc] init]; + _hostingView.delegate = self; + } + + return self; +} + +@end diff --git a/infer/tests/build_systems/objc_retain_cycles/Makefile b/infer/tests/build_systems/objc_retain_cycles/Makefile new file mode 100644 index 000000000..21287af8a --- /dev/null +++ b/infer/tests/build_systems/objc_retain_cycles/Makefile @@ -0,0 +1,23 @@ +# 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. + +TESTS_DIR = ../.. +ROOT_DIR = $(TESTS_DIR)/../.. +CODETOANALYZE_DIR = ../codetoanalyze/objc_retain_cycles + +ANALYZER = checkers +SOURCES = $(CODETOANALYZE_DIR)/View.m $(CODETOANALYZE_DIR)/ViewController.m $(CODETOANALYZE_DIR)/Caller.m +OBJECTS = $(CODETOANALYZE_DIR)/View.o $(CODETOANALYZE_DIR)/ViewController.o $(CODETOANALYZE_DIR)/Caller.o +INFER_OPTIONS = --biabduction-only --report-custom-error --developer-mode --project-root $(TESTS_DIR) +INFERPRINT_OPTIONS = --project-root $(TESTS_DIR) --issues-tests + +include $(TESTS_DIR)/infer.make + +infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(MAKEFILE_LIST) + $(QUIET)$(REMOVE_DIR) buck-out && \ + $(call silent_on_success,Testing analysis with Objective-C getters and setters,\ + $(INFER_BIN) $(INFER_OPTIONS) --results-dir $(CURDIR)/infer-out -- clang -c -fobjc-arc $(SOURCES)) diff --git a/infer/tests/build_systems/objc_retain_cycles/issues.exp b/infer/tests/build_systems/objc_retain_cycles/issues.exp new file mode 100644 index 000000000..e69de29bb