From ae8067ea1ad830287ac6d0d93b2c8281ee24b3f7 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Mon, 5 Mar 2018 08:43:17 -0800 Subject: [PATCH] [clang] Set up the objc accessor flags correctly in case property is defined in protocol Reviewed By: mbouaziz Differential Revision: D7138689 fbshipit-source-id: c30ee70 --- infer/src/IR/QualifiedCppName.ml | 8 ++++++++ infer/src/IR/QualifiedCppName.mli | 2 ++ infer/src/clang/cMethod_trans.ml | 11 ++++------- .../tests/codetoanalyze/objc/errors/issues.exp | 1 + .../RetainCyclePropertyInProtocol.m | 18 ++++++++++++++++-- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/infer/src/IR/QualifiedCppName.ml b/infer/src/IR/QualifiedCppName.ml index 0ad909560..87a5b91dc 100644 --- a/infer/src/IR/QualifiedCppName.ml +++ b/infer/src/IR/QualifiedCppName.ml @@ -46,6 +46,14 @@ let of_rev_list = ident let cpp_separator = "::" +let from_field_qualified_name name_decl_info = + match name_decl_info.Clang_ast_t.ni_qual_name with + | _ :: rest -> + rest + | _ -> + L.(die InternalError) "expected non-empty qualified name" + + (* define [cpp_separator_regex] here to compute it once *) let cpp_separator_regex = Str.regexp_string cpp_separator diff --git a/infer/src/IR/QualifiedCppName.mli b/infer/src/IR/QualifiedCppName.mli index f28817c13..30bba437b 100644 --- a/infer/src/IR/QualifiedCppName.mli +++ b/infer/src/IR/QualifiedCppName.mli @@ -47,6 +47,8 @@ val of_list : string list -> t val of_rev_list : string list -> t (** given reversed list of qualifiers, produce qualified name (ie. ["move", "std"] for std::move )*) +val from_field_qualified_name : Clang_ast_t.named_decl_info -> t + val pp : Format.formatter -> t -> unit (** Module to match qualified C++ procnames "fuzzily", that is up to namescapes and templating. In diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index d0ad0b092..52a98f7f8 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -518,16 +518,13 @@ let get_objc_property_accessor tenv ms = -> ( let ivar_decl_ref = obj_c_property_decl_info.Clang_ast_t.opdi_ivar_decl in match CAst_utils.get_decl_opt_with_decl_ref ivar_decl_ref with - | Some ObjCIvarDecl (_, {ni_name}, _, _, _) + | Some ObjCIvarDecl (_, name_decl_info, _, _, _) -> ( let class_tname = - match ms.CMethodSignature.name with - | Typ.Procname.ObjC_Cpp objc_cpp -> - Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp - | _ -> - assert false + Typ.Name.Objc.from_qual_name + (QualifiedCppName.from_field_qualified_name name_decl_info) in - let field_name = CGeneral_utils.mk_class_field_name class_tname ni_name in + let field_name = CGeneral_utils.mk_class_field_name class_tname name_decl_info.ni_name in match Tenv.lookup tenv class_tname with | Some {fields} -> ( diff --git a/infer/tests/codetoanalyze/objc/errors/issues.exp b/infer/tests/codetoanalyze/objc/errors/issues.exp index 7f0ba7c5a..58a1b0867 100644 --- a/infer/tests/codetoanalyze/objc/errors/issues.exp +++ b/infer/tests/codetoanalyze/objc/errors/issues.exp @@ -32,6 +32,7 @@ codetoanalyze/objc/errors/initialization/struct_initlistexpr.c, point_coords_set codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, call_retain_self_in_block_cycle, 2, RETAIN_CYCLE, [start of procedure call_retain_self_in_block_cycle(),start of procedure retain_self_in_block,return from a call to RCBlock_retain_self_in_block] codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, retain_a_in_block_cycle, 5, RETAIN_CYCLE, [start of procedure retain_a_in_block_cycle()] codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, retain_a_in_block_cycle, 5, RETAIN_CYCLE, [start of procedure retain_a_in_block_cycle()] +codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m, main_bad, 2, RETAIN_CYCLE, [start of procedure main_bad(),start of procedure loadViewBad,return from a call to MyCustomViewController_loadViewBad] codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle.m, strongcycle, 6, RETAIN_CYCLE, [start of procedure strongcycle()] codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m, strongcycle2, 4, RETAIN_CYCLE, [start of procedure strongcycle2(),start of procedure init,return from a call to Parent_init,start of procedure init,return from a call to Child_init,start of procedure setChild:,return from a call to Parent_setChild:,start of procedure setParent:,return from a call to Child_setParent:] codetoanalyze/objc/errors/npe/UpdateDict.m, add_nil_in_dict, 10, NULL_DEREFERENCE, [start of procedure add_nil_in_dict(),Skipping dictionaryWithObjectsAndKeys:: function or method not found] diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m index dfe756b17..ca45bc267 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCyclePropertyInProtocol.m @@ -10,6 +10,7 @@ @protocol Delegate @property(nonatomic, weak, readwrite) id delegate; +@property(nonatomic, strong, readwrite) id strong_delegate; @end @interface MyCustomView : NSObject @@ -18,6 +19,7 @@ @implementation MyCustomView @synthesize delegate = _delegate; +@synthesize strong_delegate = _strong_delegate; - (instancetype)initWithDelegate:(id)delegate { _delegate = delegate; @@ -32,15 +34,27 @@ @implementation MyCustomViewController -- (void)loadView { +- (void)loadViewGood { MyCustomView* _myView = [[MyCustomView alloc] initWithDelegate:self]; self.view = _myView; } +- (void)loadViewBad { + MyCustomView* _myView = [[MyCustomView alloc] init]; + self.view = _myView; + _myView.strong_delegate = self; +} + @end int main_good() { MyCustomViewController* controller = [MyCustomViewController new]; - [controller loadView]; + [controller loadViewGood]; + return 0; +} + +int main_bad() { + MyCustomViewController* controller = [MyCustomViewController new]; + [controller loadViewBad]; return 0; }