[clang] Find fields from the properties corresponding to the property implementations.

Summary: When a property was defined in a protocol, we were not translating its attributes which leads to retain cycles false positives. This diff fixes it. It also refactors the code for translating fields a bit.

Reviewed By: mbouaziz

Differential Revision: D7136355

fbshipit-source-id: b5e7445
master
Dulma Churchill 7 years ago committed by Facebook Github Bot
parent 569efd4c4a
commit 9f343853ec

@ -66,31 +66,38 @@ let build_sil_field qual_type_to_sil_type tenv class_tname field_name qual_type
(* Given a list of declarations in an interface returns a list of fields *) (* Given a list of declarations in an interface returns a list of fields *)
let rec get_fields qual_type_to_sil_type tenv class_tname decl_list = let get_fields qual_type_to_sil_type tenv class_tname decl_list =
let open Clang_ast_t in let open Clang_ast_t in
let add_field name_info (qt: qual_type) attributes decl_list' = let get_sil_field name_info (qt: qual_type) property_attributes =
let fields = get_fields qual_type_to_sil_type tenv class_tname decl_list' in build_sil_field qual_type_to_sil_type tenv class_tname name_info qt property_attributes
let field_tuple =
build_sil_field qual_type_to_sil_type tenv class_tname name_info qt attributes
in
CGeneral_utils.append_no_duplicates_fields [field_tuple] fields
in in
match decl_list with let rec get_field fields decl =
| [] -> match decl with
[] | ObjCPropertyDecl (_, _, obj_c_property_decl_info)
| (ObjCPropertyDecl (_, _, obj_c_property_decl_info)) :: decl_list' -> (
-> ( let ivar_decl_ref = obj_c_property_decl_info.Clang_ast_t.opdi_ivar_decl in
let ivar_decl_ref = obj_c_property_decl_info.Clang_ast_t.opdi_ivar_decl in let property_attributes = obj_c_property_decl_info.Clang_ast_t.opdi_property_attributes in
match CAst_utils.get_decl_opt_with_decl_ref ivar_decl_ref with match CAst_utils.get_decl_opt_with_decl_ref ivar_decl_ref with
| Some ObjCIvarDecl (_, name_info, qual_type, _, _) -> | Some ObjCIvarDecl (_, name_info, qual_type, _, _) ->
let attributes = obj_c_property_decl_info.Clang_ast_t.opdi_property_attributes in let field = get_sil_field name_info qual_type property_attributes in
add_field name_info qual_type attributes decl_list' CGeneral_utils.add_no_duplicates_fields field fields
| _ -> | _ ->
get_fields qual_type_to_sil_type tenv class_tname decl_list' ) fields )
| (ObjCIvarDecl (_, name_info, qual_type, _, _)) :: decl_list' -> | ObjCPropertyImplDecl (_, obj_c_property_impl_decl_info)
add_field name_info qual_type [] decl_list' -> (
| _ :: decl_list' -> let property_decl_opt = obj_c_property_impl_decl_info.Clang_ast_t.opidi_property_decl in
get_fields qual_type_to_sil_type tenv class_tname decl_list' match CAst_utils.get_decl_opt_with_decl_ref property_decl_opt with
| Some decl ->
get_field fields decl
| None ->
fields )
| ObjCIvarDecl (_, name_info, qual_type, _, _) ->
let field = get_sil_field name_info qual_type [] in
CGeneral_utils.add_no_duplicates_fields field fields
| _ ->
fields
in
List.fold ~f:get_field ~init:[] decl_list
(* Add potential extra fields defined only in the implementation of the class *) (* Add potential extra fields defined only in the implementation of the class *)

@ -13,9 +13,10 @@ open! IStd
type var_info = Clang_ast_t.decl_info * Clang_ast_t.qual_type * Clang_ast_t.var_decl_info * bool type var_info = Clang_ast_t.decl_info * Clang_ast_t.qual_type * Clang_ast_t.var_decl_info * bool
val add_no_duplicates_fields : Typ.Struct.field -> Typ.Struct.field list -> Typ.Struct.field list
val append_no_duplicates_fields : val append_no_duplicates_fields :
(Typ.Fieldname.t * Typ.t * Annot.Item.t) list -> (Typ.Fieldname.t * Typ.t * Annot.Item.t) list Typ.Struct.field list -> Typ.Struct.field list -> Typ.Struct.field list
-> (Typ.Fieldname.t * Typ.t * Annot.Item.t) list
val swap_elements_list : 'a list -> 'a list val swap_elements_list : 'a list -> 'a list

@ -94,6 +94,7 @@ SOURCES_ARC = \
memory_leaks_benchmark/retain_cycle.m \ memory_leaks_benchmark/retain_cycle.m \
memory_leaks_benchmark/retain_cycle2.m \ memory_leaks_benchmark/retain_cycle2.m \
memory_leaks_benchmark/RetainCycleBlocks.m \ memory_leaks_benchmark/RetainCycleBlocks.m \
memory_leaks_benchmark/RetainCyclePropertyInProtocol.m \
npe/BoxedNumberExample.m \ npe/BoxedNumberExample.m \
npe/ObjCMethodCallInCondition.m \ npe/ObjCMethodCallInCondition.m \
npe/UpdateDict.m \ npe/UpdateDict.m \

@ -0,0 +1,46 @@
/*
* 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 <Foundation/NSObject.h>
@protocol Delegate
@property(nonatomic, weak, readwrite) id delegate;
@end
@interface MyCustomView : NSObject<Delegate>
- (instancetype)initWithDelegate:(id)delegate;
@end
@implementation MyCustomView
@synthesize delegate = _delegate;
- (instancetype)initWithDelegate:(id)delegate {
_delegate = delegate;
return self;
}
@end
@interface MyCustomViewController : NSObject
@property(nonatomic, strong, readwrite) id view;
@end
@implementation MyCustomViewController
- (void)loadView {
MyCustomView* _myView = [[MyCustomView alloc] initWithDelegate:self];
self.view = _myView;
}
@end
int main_good() {
MyCustomViewController* controller = [MyCustomViewController new];
[controller loadView];
return 0;
}
Loading…
Cancel
Save