You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
3.0 KiB

(*
* Copyright (c) 2015 - 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.
*)
open CFrontend_utils
open General_utils
(* === Warnings on properties === *)
(* Strong Delegate Warning: a property with name delegate should not be declared strong *)
let checker_strong_delegate_warning class_decl_info pname ptype =
Printing.log_out "Checking for STRONG_DELEGATE property warning\n";
let delegate_regexp = Str.regexp_string_case_fold "delegate" in
let pname_contains_delegate = try
Str.search_forward delegate_regexp pname.Clang_ast_t.ni_name 0 >= 0
with Not_found -> false in
let condition = pname_contains_delegate
&& ObjcProperty_decl.is_strong_property ptype in
let warning_desc =
{ name = "STRONG_DELEGATE_WARNING";
description = "Property or ivar "^pname.Clang_ast_t.ni_name^" declared strong";
suggestion = "In general delegates should be declared weak or assign";
loc = CLocation.get_sil_location_from_range class_decl_info.Clang_ast_t.di_source_range true;
} in
(condition, warning_desc)
(* Direct Atomic Property access:
a property declared atomic should not be accessed directly via its ivar *)
let direct_atomic_property_access context stmt_info ivar_name =
let tenv = CContext.get_tenv context in
let mname = Cfg.Procdesc.get_proc_name (CContext.get_procdesc context) in
let ivar, cname = match ivar_name with
| Some n ->
General_utils.mk_class_field_name n,
Ast_utils.get_class_name_from_member n
| _ -> Ident.create_fieldname (Mangled.from_string "") 0, "" in
let tname = Sil.TN_csu (Sil.Class, Mangled.from_string cname) in
let loc = CLocation.get_sil_location_from_range stmt_info.Clang_ast_t.si_source_range true in
match Sil.tenv_lookup tenv tname with
| Some Sil.Tstruct (flds1, flds2, _, _, _, _, _) ->
(* We give the warning when:
(1) the property has the atomic attribute and
(2) the access of the ivar is not in a getter or setter method.
(3) the access of the ivar is not in the init method
Last two conditions avoids false positives *)
let condition = (CField_decl.is_ivar_atomic ivar (flds1 @ flds2))
&& not (CContext.is_curr_proc_objc_getter context ivar)
&& not (CContext.is_curr_proc_objc_setter context ivar)
&& not (Procname.is_constructor mname) in
let warning_desc = {
name = "DIRECT_ATOMIC_PROPERTY_ACCESS";
description = "Direct access to ivar " ^ (Ident.fieldname_to_string ivar) ^
" of an atomic property";
suggestion = "Accessing an ivar of an atomic property makes the property nonatomic";
loc = loc;
} in
(condition, Some warning_desc)
| _ -> (false, None) (* No warning *)