[frontend] Track protocols in A<ObjCProtocol>

Reviewed By: skcho

Differential Revision: D24566435

fbshipit-source-id: 62d41c8c6
master
Ezgi Çiçek 4 years ago committed by Facebook GitHub Bot
parent 47fad6eaf3
commit 9111526a5e

@ -17,11 +17,11 @@
id a = ((NSObject*)aKey)->isa; id a = ((NSObject*)aKey)->isa;
} }
- (void)setObject:(id)object forKeyedSubscript:(id)aKey { - (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)aKey {
id a = ((NSObject*)aKey)->isa; id a = ((NSObject*)aKey)->isa;
} }
- (void)setObject:(id)anObject forKey:(id)aKey { - (void)setObject:(id)anObject forKey:(id<NSCopying>)aKey {
id a = ((NSObject*)anObject)->isa; id a = ((NSObject*)anObject)->isa;
id b = ((NSObject*)aKey)->isa; id b = ((NSObject*)aKey)->isa;
} }

@ -38,6 +38,14 @@ let append_template_args_to_last quals ~args =
raise (ParseError "expected non-empty qualified name") raise (ParseError "expected non-empty qualified name")
let append_protocols quals ~protocols =
match quals with
| last :: rest ->
(last ^ protocols) :: rest
| [] ->
raise (ParseError "expected non-empty qualified name")
let to_list = List.rev let to_list = List.rev
let to_rev_list = ident let to_rev_list = ident

@ -36,6 +36,9 @@ val append_template_args_to_last : t -> args:string -> t
(** append template arguments to the last qualifier. Fails if qualified name is empty or it already (** append template arguments to the last qualifier. Fails if qualified name is empty or it already
has template args *) has template args *)
val append_protocols : t -> protocols:string -> t
(** append protocols to the qualified name *)
val to_list : t -> string list val to_list : t -> string list
(** returns list of qualifiers *) (** returns list of qualifiers *)

@ -184,7 +184,7 @@ module T = struct
| CUnion of QualifiedCppName.t | CUnion of QualifiedCppName.t
| CppClass of QualifiedCppName.t * template_spec_info | CppClass of QualifiedCppName.t * template_spec_info
| JavaClass of JavaClassName.t | JavaClass of JavaClassName.t
| ObjcClass of QualifiedCppName.t | ObjcClass of QualifiedCppName.t * name list
| ObjcProtocol of QualifiedCppName.t | ObjcProtocol of QualifiedCppName.t
and template_arg = TType of t | TInt of int64 | TNull | TNullPtr | TOpaque and template_arg = TType of t | TInt of int64 | TNull | TNullPtr | TOpaque
@ -275,39 +275,37 @@ let rec pp_full pe f typ =
if is_restrict quals then F.pp_print_string f " __restrict " ; if is_restrict quals then F.pp_print_string f " __restrict " ;
if is_volatile quals then F.pp_print_string f " volatile " if is_volatile quals then F.pp_print_string f " volatile "
in in
let pp_desc f {desc} = F.fprintf f "%a%a" (pp_desc pe) typ.desc pp_quals typ
match desc with
| Tstruct tname ->
(pp_name_c_syntax pe) f tname and pp_desc pe f desc =
| TVar name -> match desc with
F.pp_print_string f name | Tstruct tname ->
| Tint ik -> (pp_name_c_syntax pe) f tname
F.pp_print_string f (ikind_to_string ik) | TVar name ->
| Tfloat fk -> F.pp_print_string f name
F.pp_print_string f (fkind_to_string fk) | Tint ik ->
| Tvoid -> F.pp_print_string f (ikind_to_string ik)
F.pp_print_string f "void" | Tfloat fk ->
| Tfun -> F.pp_print_string f (fkind_to_string fk)
F.pp_print_string f "_fn_" | Tvoid ->
| Tptr (({desc= Tarray _ | Tfun} as typ), pk) -> F.pp_print_string f "void"
F.fprintf f "%a(%s)" (pp_full pe) typ (ptr_kind_string pk |> escape pe) | Tfun ->
| Tptr (typ, pk) -> F.pp_print_string f "_fn_"
F.fprintf f "%a%s" (pp_full pe) typ (ptr_kind_string pk |> escape pe) | Tptr (({desc= Tarray _ | Tfun} as typ), pk) ->
| Tarray {elt; length; stride} -> F.fprintf f "%a(%s)" (pp_full pe) typ (ptr_kind_string pk |> escape pe)
let pp_int_opt fmt = function | Tptr (typ, pk) ->
| Some x -> F.fprintf f "%a%s" (pp_full pe) typ (ptr_kind_string pk |> escape pe)
IntLit.pp fmt x | Tarray {elt; length; stride} ->
| None -> let pp_int_opt fmt = function Some x -> IntLit.pp fmt x | None -> F.pp_print_char fmt '_' in
F.pp_print_char fmt '_' F.fprintf f "%a[%a*%a]" (pp_full pe) elt pp_int_opt length pp_int_opt stride
in
F.fprintf f "%a[%a*%a]" (pp_full pe) elt pp_int_opt length pp_int_opt stride
in
F.fprintf f "%a%a" pp_desc typ pp_quals typ
and pp_name_c_syntax pe f = function and pp_name_c_syntax pe f = function
| CStruct name | CUnion name | ObjcClass name | ObjcProtocol name -> | CStruct name | CUnion name | ObjcProtocol name ->
QualifiedCppName.pp f name QualifiedCppName.pp f name
| ObjcClass (name, protocol_names) ->
F.fprintf f "%a%a" QualifiedCppName.pp name (pp_protocols pe) protocol_names
| CppClass (name, template_spec) -> | CppClass (name, template_spec) ->
F.fprintf f "%a%a" QualifiedCppName.pp name (pp_template_spec_info pe) template_spec F.fprintf f "%a%a" QualifiedCppName.pp name (pp_template_spec_info pe) template_spec
| JavaClass name -> | JavaClass name ->
@ -333,6 +331,14 @@ and pp_template_spec_info pe f = function
F.fprintf f "%s%a%s" (escape pe "<") (Pp.comma_seq pp_arg_opt) args (escape pe ">") F.fprintf f "%s%a%s" (escape pe "<") (Pp.comma_seq pp_arg_opt) args (escape pe ">")
and pp_protocols pe f protocols =
if List.is_empty protocols then ()
else
F.fprintf f "%s%a%s" (escape pe "<")
(Pp.comma_seq (pp_name_c_syntax pe))
protocols (escape pe ">")
(** Pretty print a type. Do nothing by default. *) (** Pretty print a type. Do nothing by default. *)
let pp pe f te = if Config.print_types then pp_full pe f te else () let pp pe f te = if Config.print_types then pp_full pe f te else ()
@ -341,14 +347,22 @@ let to_string typ =
F.asprintf "%t" pp F.asprintf "%t" pp
let desc_to_string desc =
let pp fmt = pp_desc Pp.text fmt desc in
F.asprintf "%t" pp
module Name = struct module Name = struct
type t = name [@@deriving compare, equal, yojson_of] type t = name [@@deriving compare, equal, yojson_of]
let hash = Hashtbl.hash let hash = Hashtbl.hash
let qual_name = function let qual_name = function
| CStruct name | CUnion name | ObjcClass name | ObjcProtocol name -> | CStruct name | CUnion name | ObjcProtocol name ->
name name
| ObjcClass (name, protocol_names) ->
let protocols = F.asprintf "%a" (pp_protocols Pp.text) protocol_names in
QualifiedCppName.append_protocols name ~protocols
| CppClass (name, templ_args) -> | CppClass (name, templ_args) ->
let template_suffix = F.asprintf "%a" (pp_template_spec_info Pp.text) templ_args in let template_suffix = F.asprintf "%a" (pp_template_spec_info Pp.text) templ_args in
QualifiedCppName.append_template_args_to_last name ~args:template_suffix QualifiedCppName.append_template_args_to_last name ~args:template_suffix
@ -357,7 +371,7 @@ module Name = struct
let unqualified_name = function let unqualified_name = function
| CStruct name | CUnion name | ObjcClass name | ObjcProtocol name -> | CStruct name | CUnion name | ObjcProtocol name | ObjcClass (name, _) ->
name name
| CppClass (name, _) -> | CppClass (name, _) ->
name name
@ -457,7 +471,7 @@ module Name = struct
end end
module Objc = struct module Objc = struct
let from_qual_name qual_name = ObjcClass qual_name let from_qual_name qual_name = ObjcClass (qual_name, [])
let from_string name_str = QualifiedCppName.of_qual_string name_str |> from_qual_name let from_string name_str = QualifiedCppName.of_qual_string name_str |> from_qual_name
@ -483,7 +497,8 @@ module Name = struct
|> List.map ~f:QualifiedCppName.of_qual_string |> List.map ~f:QualifiedCppName.of_qual_string
|> QualifiedCppName.Set.of_list |> QualifiedCppName.Set.of_list
in in
function ObjcClass name -> not (QualifiedCppName.Set.mem name tagged_classes) | _ -> false function
| ObjcClass (name, _) -> not (QualifiedCppName.Set.mem name tagged_classes) | _ -> false
end end
module Set = PrettyPrintable.MakePPSet (struct module Set = PrettyPrintable.MakePPSet (struct

@ -107,7 +107,9 @@ and name =
"MyClass<int>", "InnerClass" *) "MyClass<int>", "InnerClass" *)
| CppClass of QualifiedCppName.t * template_spec_info | CppClass of QualifiedCppName.t * template_spec_info
| JavaClass of JavaClassName.t | JavaClass of JavaClassName.t
| ObjcClass of QualifiedCppName.t | ObjcClass of QualifiedCppName.t * name list
(* ObjC class that conforms to a list of protocols,
e.g. id<NSFastEnumeration, NSCopying> *)
| ObjcProtocol of QualifiedCppName.t | ObjcProtocol of QualifiedCppName.t
and template_arg = TType of t | TInt of Int64.t | TNull | TNullPtr | TOpaque and template_arg = TType of t | TInt of Int64.t | TNull | TNullPtr | TOpaque
@ -251,11 +253,18 @@ val pp_full : Pp.env -> F.formatter -> t -> unit
val pp : Pp.env -> F.formatter -> t -> unit val pp : Pp.env -> F.formatter -> t -> unit
(** Pretty print a type. *) (** Pretty print a type. *)
val pp_desc : Pp.env -> F.formatter -> desc -> unit
(** Pretty print a type desc. *)
val pp_java : verbose:bool -> F.formatter -> t -> unit val pp_java : verbose:bool -> F.formatter -> t -> unit
(** Pretty print a Java type. Raises if type isn't produced by the Java frontend *) (** Pretty print a Java type. Raises if type isn't produced by the Java frontend *)
val pp_protocols : Pp.env -> F.formatter -> name list -> unit
val to_string : t -> string val to_string : t -> string
val desc_to_string : desc -> string
val d_full : t -> unit val d_full : t -> unit
(** Dump a type with all the details. *) (** Dump a type with all the details. *)

@ -301,9 +301,17 @@ module ObjectiveC = struct
supertype_exists tenv is_interface (Typ.Name.Objc.from_string typename) supertype_exists tenv is_interface (Typ.Name.Objc.from_string typename)
let conforms_to ~protocol tenv typename = let conforms_to =
let is_protocol s = String.equal protocol (Typ.Name.name s) in let protocol_reg = Str.regexp ".+<\\(.+\\)>" in
protocol_exists tenv is_protocol (Typ.Name.Objc.from_string typename) fun ~protocol tenv typename ->
let is_protocol s = String.equal protocol (Typ.Name.name s) in
protocol_exists tenv is_protocol (Typ.Name.Objc.from_string typename)
|| (* Corresponds to the case where we look inside protocols in
ObjCClass<P1,P2...Pn> *)
Str.string_match protocol_reg typename 0
&&
let conformed_protocols = Str.matched_group 1 typename |> String.split ~on:',' in
List.exists conformed_protocols ~f:(String.equal protocol)
let implements_collection = let implements_collection =

@ -43,8 +43,11 @@ let template_args_of_template_spec_info = function
let templated_name_of_class_name class_name = let templated_name_of_class_name class_name =
let open Typ in let open Typ in
match class_name with match class_name with
| CStruct qual_name | CUnion qual_name | ObjcClass qual_name | ObjcProtocol qual_name -> | CStruct qual_name | CUnion qual_name | ObjcProtocol qual_name ->
(qual_name, []) (qual_name, [])
| ObjcClass (qual_name, protocol_names) ->
let protocols = F.asprintf "%a" (Typ.pp_protocols Pp.text) protocol_names in
(QualifiedCppName.append_protocols qual_name ~protocols, [])
| CppClass (qual_name, template_spec_info) -> | CppClass (qual_name, template_spec_info) ->
(qual_name, template_args_of_template_spec_info template_spec_info) (qual_name, template_args_of_template_spec_info template_spec_info)
| JavaClass mangled_name -> | JavaClass mangled_name ->

@ -13,18 +13,20 @@ module L = Logging
let add_pointer_to_typ typ = Typ.mk (Tptr (typ, Typ.Pk_pointer)) let add_pointer_to_typ typ = Typ.mk (Tptr (typ, Typ.Pk_pointer))
let objc_classname_of_type typ = let objc_classname_of_desc desc =
match typ.Typ.desc with match (desc : Typ.desc) with
| Typ.Tstruct name -> | Tstruct name ->
name name
| Typ.Tfun -> | Tfun ->
Typ.Name.Objc.from_string CFrontend_config.objc_object Typ.Name.Objc.from_string CFrontend_config.objc_object
| _ -> | _ ->
L.(debug Capture Verbose) L.(debug Capture Verbose)
"Classname of type cannot be extracted in type %s" (Typ.to_string typ) ; "Classname of type cannot be extracted in %s" (Typ.desc_to_string desc) ;
Typ.Name.Objc.from_string "undefined" Typ.Name.Objc.from_string "undefined"
let objc_classname_of_type Typ.{desc} = objc_classname_of_desc desc
let is_class typ = let is_class typ =
match typ.Typ.desc with match typ.Typ.desc with
| Typ.Tptr ({desc= Tstruct name}, _) -> | Typ.Tptr ({desc= Tstruct name}, _) ->

@ -13,6 +13,8 @@ val add_pointer_to_typ : Typ.t -> Typ.t
val objc_classname_of_type : Typ.t -> Typ.Name.t val objc_classname_of_type : Typ.t -> Typ.Name.t
val objc_classname_of_desc : Typ.desc -> Typ.Name.t
val is_class : Typ.t -> bool val is_class : Typ.t -> bool
val return_type_of_function_type : Clang_ast_t.qual_type -> Clang_ast_t.qual_type val return_type_of_function_type : Clang_ast_t.qual_type -> Clang_ast_t.qual_type

@ -92,7 +92,7 @@ let get_class_name_method_call_from_clang tenv obj_c_message_expr_info =
None None
(* Get class name from a method call accorsing to the info given by the receiver kind *) (* Get class name from a method call according to the info given by the receiver kind *)
let get_class_name_method_call_from_receiver_kind context obj_c_message_expr_info act_params = let get_class_name_method_call_from_receiver_kind context obj_c_message_expr_info act_params =
match obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind with match obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind with
| `Class qt -> | `Class qt ->

@ -91,6 +91,28 @@ let pointer_attribute_of_objc_attribute attr_info =
Typ.Pk_objc_autoreleasing Typ.Pk_objc_autoreleasing
let add_protocols_to_desc tenv desc protocol_desc_list =
let rec add_nonempty_protocol desc =
match (desc : Typ.desc) with
| Tstruct (CStruct nm | ObjcClass (nm, _)) ->
let objc_protocols = List.map ~f:CType.objc_classname_of_desc protocol_desc_list in
let name = Typ.ObjcClass (nm, objc_protocols) in
ignore (Tenv.mk_struct tenv name ~objc_protocols) ;
let desc = Typ.Tstruct name in
Logging.(debug Analysis Verbose)
"@.Found class with protocols, replacing the existing desc with %a.. \n"
(Typ.pp_desc Pp.text) desc ;
desc
| Tptr (Typ.{desc; quals}, pkind) ->
Typ.Tptr ({desc= add_nonempty_protocol desc; quals}, pkind)
| Tarray Typ.{elt= {desc; quals}; length; stride} ->
Typ.Tarray {elt= {desc= add_nonempty_protocol desc; quals}; length; stride}
| _ ->
desc
in
if List.is_empty protocol_desc_list then desc else add_nonempty_protocol desc
let rec build_array_type translate_decl tenv (qual_type : Clang_ast_t.qual_type) length_opt let rec build_array_type translate_decl tenv (qual_type : Clang_ast_t.qual_type) length_opt
stride_opt = stride_opt =
let array_type = qual_type_to_sil_type translate_decl tenv qual_type in let array_type = qual_type_to_sil_type translate_decl tenv qual_type in
@ -126,7 +148,14 @@ and type_desc_of_c_type translate_decl tenv c_type : Typ.desc =
if Typ.equal_desc desc (get_builtin_objc_type `ObjCClass) then desc if Typ.equal_desc desc (get_builtin_objc_type `ObjCClass) then desc
else Typ.Tptr (typ, Typ.Pk_pointer) else Typ.Tptr (typ, Typ.Pk_pointer)
| ObjCObjectType (_, objc_object_type_info) -> | ObjCObjectType (_, objc_object_type_info) ->
type_ptr_to_type_desc translate_decl tenv objc_object_type_info.Clang_ast_t.ooti_base_type let protocol_decls_ptr = objc_object_type_info.Clang_ast_t.ooti_protocol_decls_ptr in
let protocol_desc_list =
List.map protocol_decls_ptr ~f:(fun pointer ->
decl_ptr_to_type_desc translate_decl tenv pointer )
in
let type_ptr = objc_object_type_info.Clang_ast_t.ooti_base_type in
let desc = type_ptr_to_type_desc translate_decl tenv type_ptr in
add_protocols_to_desc tenv desc protocol_desc_list
| BlockPointerType (_, qual_type) -> | BlockPointerType (_, qual_type) ->
let typ = qual_type_to_sil_type translate_decl tenv qual_type in let typ = qual_type_to_sil_type translate_decl tenv qual_type in
Typ.Tptr (typ, Typ.Pk_pointer) Typ.Tptr (typ, Typ.Pk_pointer)

@ -18,7 +18,7 @@ digraph cfg {
"get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_2" [label="2: Exit get_array2 \n " color=yellow style=filled] "get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_2" [label="2: Exit get_array2 \n " color=yellow style=filled]
"get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_3" [label="3: Return Stmt \n n$2=_fun_NSString.stringWithUTF8String:(\"firstName\":char* const ) [line 23, column 12]\n n$3=_fun_NSString.stringWithUTF8String:(\"Matt\":char* const ) [line 23, column 27]\n n$4=_fun_NSString.stringWithUTF8String:(\"lastName\":char* const ) [line 23, column 36]\n n$5=_fun_NSString.stringWithUTF8String:(\"Galloway\":char* const ) [line 23, column 50]\n n$6=_fun_NSString.stringWithUTF8String:(\"age\":char* const ) [line 23, column 63]\n n$7=_fun_NSNumber.numberWithInt:(28:int) [line 23, column 72]\n _=*n$3:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[0]:objc_object*=n$3 [line 23, column 10]\n _=*n$5:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[1]:objc_object*=n$5 [line 23, column 10]\n _=*n$7:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[2]:objc_object*=n$7 [line 23, column 10]\n _=*n$2:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[0]:objc_object*=n$2 [line 23, column 10]\n _=*n$4:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[1]:objc_object*=n$4 [line 23, column 10]\n _=*n$6:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[2]:objc_object*=n$6 [line 23, column 10]\n n$9=_fun_NSDictionary.dictionaryWithObjects:forKeys:count:(&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0:objc_object* const [6*8],&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1:objc_object* const [6*8],3:int) [line 23, column 10]\n *&return:NSDictionary*=n$9 [line 23, column 3]\n " shape="box"] "get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_3" [label="3: Return Stmt \n n$2=_fun_NSString.stringWithUTF8String:(\"firstName\":char* const ) [line 23, column 12]\n n$3=_fun_NSString.stringWithUTF8String:(\"Matt\":char* const ) [line 23, column 27]\n n$4=_fun_NSString.stringWithUTF8String:(\"lastName\":char* const ) [line 23, column 36]\n n$5=_fun_NSString.stringWithUTF8String:(\"Galloway\":char* const ) [line 23, column 50]\n n$6=_fun_NSString.stringWithUTF8String:(\"age\":char* const ) [line 23, column 63]\n n$7=_fun_NSNumber.numberWithInt:(28:int) [line 23, column 72]\n _=*n$3:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[0]:objc_object*=n$3 [line 23, column 10]\n _=*n$5:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[1]:objc_object*=n$5 [line 23, column 10]\n _=*n$7:objc_object* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[2]:objc_object*=n$7 [line 23, column 10]\n _=*n$2:objc_object<NSCopying>* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[0]:objc_object<NSCopying>*=n$2 [line 23, column 10]\n _=*n$4:objc_object<NSCopying>* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[1]:objc_object<NSCopying>*=n$4 [line 23, column 10]\n _=*n$6:objc_object<NSCopying>* [line 23, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[2]:objc_object<NSCopying>*=n$6 [line 23, column 10]\n n$9=_fun_NSDictionary.dictionaryWithObjects:forKeys:count:(&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0:objc_object* const [6*8],&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1:objc_object* const [6*8],3:int) [line 23, column 10]\n *&return:NSDictionary*=n$9 [line 23, column 3]\n " shape="box"]
"get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_3" -> "get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_2" ; "get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_3" -> "get_array2.84aa3c70cb20e7edbe4f0b8d0bd6aa3d_2" ;

@ -18,7 +18,7 @@ digraph cfg {
"isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_2" [label="2: Exit ASDisplayNode.isOpaque \n " color=yellow style=filled] "isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_2" [label="2: Exit ASDisplayNode.isOpaque \n " color=yellow style=filled]
"isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_3" [label="3: BinaryOperatorStmt: Node \n n$2=*&self:ASDisplayNode* [line 12, column 41]\n n$3=*n$2._opaque:_Bool [line 12, column 41]\n *&return:_Bool=n$3 [line 12, column 41]\n " shape="box"] "isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_3" [label="3: BinaryOperatorStmt: Node \n n$0=*&self:ASDisplayNode* [line 12, column 41]\n n$1=*n$0._opaque:_Bool [line 12, column 41]\n *&return:_Bool=n$1 [line 12, column 41]\n " shape="box"]
"isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_3" -> "isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_2" ; "isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_3" -> "isOpaque#ASDisplayNode#instance.efbf8192c0bb59de353a9d71765d463c_2" ;
@ -29,7 +29,7 @@ digraph cfg {
"setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_2" [label="2: Exit ASDisplayNode.setOpaque: \n " color=yellow style=filled] "setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_2" [label="2: Exit ASDisplayNode.setOpaque: \n " color=yellow style=filled]
"setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_3" [label="3: BinaryOperatorStmt: Node \n n$0=*&self:ASDisplayNode* [line 12, column 41]\n n$1=*&opaque:_Bool [line 12, column 41]\n *n$0._opaque:_Bool=n$1 [line 12, column 41]\n " shape="box"] "setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_3" [label="3: BinaryOperatorStmt: Node \n n$2=*&self:ASDisplayNode* [line 12, column 41]\n n$3=*&opaque:_Bool [line 12, column 41]\n *n$2._opaque:_Bool=n$3 [line 12, column 41]\n " shape="box"]
"setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_3" -> "setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_2" ; "setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_3" -> "setOpaque:#ASDisplayNode#instance.f5e64d1703bd4ab716e8ec5de489150d_2" ;

@ -29,7 +29,7 @@ digraph cfg {
"setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_2" [label="2: Exit A.setX: \n " color=yellow style=filled] "setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_2" [label="2: Exit A.setX: \n " color=yellow style=filled]
"setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_3" [label="3: BinaryOperatorStmt: Node \n n$2=*&self:A* [line 11, column 15]\n n$3=*&x:int [line 11, column 15]\n *n$2._x:int=n$3 [line 11, column 15]\n " shape="box"] "setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_3" [label="3: BinaryOperatorStmt: Node \n n$0=*&self:A* [line 11, column 15]\n n$1=*&x:int [line 11, column 15]\n *n$0._x:int=n$1 [line 11, column 15]\n " shape="box"]
"setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_3" -> "setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_2" ; "setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_3" -> "setX:#A#instance.00c5402542b9aade8ca8191be56dcd87_2" ;
@ -40,7 +40,7 @@ digraph cfg {
"x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_2" [label="2: Exit A.x \n " color=yellow style=filled] "x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_2" [label="2: Exit A.x \n " color=yellow style=filled]
"x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_3" [label="3: BinaryOperatorStmt: Node \n n$0=*&self:A* [line 11, column 15]\n n$1=*n$0._x:int [line 11, column 15]\n *&return:int=n$1 [line 11, column 15]\n " shape="box"] "x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_3" [label="3: BinaryOperatorStmt: Node \n n$2=*&self:A* [line 11, column 15]\n n$3=*n$2._x:int [line 11, column 15]\n *&return:int=n$3 [line 11, column 15]\n " shape="box"]
"x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_3" -> "x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_2" ; "x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_3" -> "x#A#instance.37ea1b3cd5342ae67c7383da2227f91f_2" ;

@ -18,8 +18,19 @@ void call_loop_enumerator_constant() {
loop_enumerator_linear(arr); loop_enumerator_linear(arr);
} }
// We get Top because front-end can't recognize NSFastEnumeration void loop_id_enumerator_linear(id<NSFastEnumeration, NSCopying> enumeration) {
void loop_id_enumerator_linear_FP(id<NSFastEnumeration> enumeration) {
for (id obj in enumeration) { for (id obj in enumeration) {
} }
} }
void call_loop_id_enumerator_linear(NSArray* arr) {
loop_id_enumerator_linear(arr);
}
@interface A : NSObject<NSCopying>
@end
void loop_enumerator_over_class_linear(A<NSFastEnumeration>* a) {
for (id obj in a) {
}
}

@ -56,8 +56,10 @@ codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_init_dictionary_cons
codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_init_literal_constant, 45, OnUIThread:false, [] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_init_literal_constant, 45, OnUIThread:false, []
codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_init_with_dictionary_linear, 7 + 3 ⋅ dict->elements.length.ub + 4 ⋅ (dict->elements.length.ub + 1), OnUIThread:false, [{dict->elements.length.ub + 1},Loop,{dict->elements.length.ub},Loop] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_init_with_dictionary_linear, 7 + 3 ⋅ dict->elements.length.ub + 4 ⋅ (dict->elements.length.ub + 1), OnUIThread:false, [{dict->elements.length.ub + 1},Loop,{dict->elements.length.ub},Loop]
codetoanalyze/objc/performance/NSEnumeration.m, call_loop_enumerator_constant, 35, OnUIThread:false, [] codetoanalyze/objc/performance/NSEnumeration.m, call_loop_enumerator_constant, 35, OnUIThread:false, []
codetoanalyze/objc/performance/NSEnumeration.m, call_loop_id_enumerator_linear, 7 + 5 ⋅ (arr->elements.length.ub + 1), OnUIThread:false, [{arr->elements.length.ub + 1},Call to loop_id_enumerator_linear,Loop]
codetoanalyze/objc/performance/NSEnumeration.m, loop_enumerator_linear, 5 + 5 ⋅ (enumeration->elements.length.ub + 1), OnUIThread:false, [{enumeration->elements.length.ub + 1},Loop] codetoanalyze/objc/performance/NSEnumeration.m, loop_enumerator_linear, 5 + 5 ⋅ (enumeration->elements.length.ub + 1), OnUIThread:false, [{enumeration->elements.length.ub + 1},Loop]
codetoanalyze/objc/performance/NSEnumeration.m, loop_id_enumerator_linear_FP, , OnUIThread:false, [Unbounded loop,Loop] codetoanalyze/objc/performance/NSEnumeration.m, loop_enumerator_over_class_linear, 5 + 5 ⋅ (a->elements.length.ub + 1), OnUIThread:false, [{a->elements.length.ub + 1},Loop]
codetoanalyze/objc/performance/NSEnumeration.m, loop_id_enumerator_linear, 5 + 5 ⋅ (enumeration->elements.length.ub + 1), OnUIThread:false, [{enumeration->elements.length.ub + 1},Loop]
codetoanalyze/objc/performance/NSFileManager.m, contents_of_directory_at_url_constant, 11, OnUIThread:false, [] codetoanalyze/objc/performance/NSFileManager.m, contents_of_directory_at_url_constant, 11, OnUIThread:false, []
codetoanalyze/objc/performance/NSInteger.m, nsinteger_value_linear, 3 + 3 ⋅ integer + 2 ⋅ (1+max(0, integer)), OnUIThread:false, [{1+max(0, integer)},Loop,{integer},Loop] codetoanalyze/objc/performance/NSInteger.m, nsinteger_value_linear, 3 + 3 ⋅ integer + 2 ⋅ (1+max(0, integer)), OnUIThread:false, [{1+max(0, integer)},Loop,{integer},Loop]
codetoanalyze/objc/performance/NSInteger.m, nsnumber_number_with_int_integer_value_constant, 34, OnUIThread:false, [] codetoanalyze/objc/performance/NSInteger.m, nsnumber_number_with_int_integer_value_constant, 34, OnUIThread:false, []

@ -3,7 +3,6 @@ codetoanalyze/objc/performance/NSArray.m, nsarray_enumerator_linear, 7, INTEGER_
codetoanalyze/objc/performance/NSArray.m, nsarray_init_constant, 3, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here] codetoanalyze/objc/performance/NSArray.m, nsarray_init_constant, 3, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here]
codetoanalyze/objc/performance/NSArray.m, nsarray_iterate_linear, 3, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Assignment,Binary operation: ([0, +oo] + [1, array->elements.length.ub + 1]):signed64] codetoanalyze/objc/performance/NSArray.m, nsarray_iterate_linear, 3, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [<LHS trace>,Assignment,<RHS trace>,Assignment,Binary operation: ([0, +oo] + [1, array->elements.length.ub + 1]):signed64]
codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_enumerate_constant, 6, BUFFER_OVERRUN_L2, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Array access: Offset: [1, 3] Size: 2] codetoanalyze/objc/performance/NSDictionary.m, nsdictionary_enumerate_constant, 6, BUFFER_OVERRUN_L2, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Array access: Offset: [1, 3] Size: 2]
codetoanalyze/objc/performance/NSEnumeration.m, loop_id_enumerator_linear_FP, 0, INFINITE_EXECUTION_TIME, no_bucket, ERROR, [Unbounded loop,Loop]
codetoanalyze/objc/performance/NSFileManager.m, contents_of_directory_at_url_constant, 7, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here] codetoanalyze/objc/performance/NSFileManager.m, contents_of_directory_at_url_constant, 7, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here]
codetoanalyze/objc/performance/NSMutableArray.m, nsarray_new_constant, 2, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here] codetoanalyze/objc/performance/NSMutableArray.m, nsarray_new_constant, 2, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [Here]
codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_remove_constant, 6, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Through,Through,Through,Through,Array access: Offset: 0 Size: 0] codetoanalyze/objc/performance/NSMutableArray.m, nsmarray_remove_constant, 6, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Through,Through,Through,Through,Array access: Offset: 0 Size: 0]

@ -7,7 +7,7 @@ digraph cfg {
"npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_2" [label="2: Exit npe_property_nullable \n " color=yellow style=filled] "npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_2" [label="2: Exit npe_property_nullable \n " color=yellow style=filled]
"npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_3" [label="3: Return Stmt \n n$2=_fun_NSString.stringWithUTF8String:(\"key\":char* const ) [line 56, column 12]\n n$3=*&child:Person* [line 56, column 21]\n _=*n$3:objc_object* [line 56, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[0]:objc_object*=n$3 [line 56, column 10]\n _=*n$2:objc_object* [line 56, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[0]:objc_object*=n$2 [line 56, column 10]\n n$5=_fun_NSDictionary.dictionaryWithObjects:forKeys:count:(&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0:objc_object* const [2*8],&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1:objc_object* const [2*8],1:int) [line 56, column 10]\n *&return:NSDictionary*=n$5 [line 56, column 3]\n " shape="box"] "npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_3" [label="3: Return Stmt \n n$2=_fun_NSString.stringWithUTF8String:(\"key\":char* const ) [line 56, column 12]\n n$3=*&child:Person* [line 56, column 21]\n _=*n$3:objc_object* [line 56, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0[0]:objc_object*=n$3 [line 56, column 10]\n _=*n$2:objc_object<NSCopying>* [line 56, column 10]\n *&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1[0]:objc_object<NSCopying>*=n$2 [line 56, column 10]\n n$5=_fun_NSDictionary.dictionaryWithObjects:forKeys:count:(&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count1___n$0:objc_object* const [2*8],&0$?%__sil_tmpSIL_dictionaryWithObjects_forKeys_count2___n$1:objc_object* const [2*8],1:int) [line 56, column 10]\n *&return:NSDictionary*=n$5 [line 56, column 3]\n " shape="box"]
"npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_3" -> "npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_2" ; "npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_3" -> "npe_property_nullable.ba4461b16b55481ab8de5124734d2bf3_2" ;

@ -101,7 +101,7 @@ digraph cfg {
"dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_3" -> "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_2" ; "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_3" -> "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_2" ;
"dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_4" [label="4: Call _fun_dispatch_after \n n$16=_fun_dispatch_time(0:unsigned long long,((unsigned long long)2 * 1000000000):long long) [line 46, column 18]\n n$17=_fun_dispatch_get_main_queue() [line 47, column 18]\n n$21=_fun_dispatch_after(n$16:unsigned long long,n$17:NSObject*,(_fun_objc_blockDispatchEx.dispatch_after_example_3):_fn_(*)) [line 46, column 3]\n " shape="box"] "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_4" [label="4: Call _fun_dispatch_after \n n$16=_fun_dispatch_time(0:unsigned long long,((unsigned long long)2 * 1000000000):long long) [line 46, column 18]\n n$17=_fun_dispatch_get_main_queue() [line 47, column 18]\n n$21=_fun_dispatch_after(n$16:unsigned long long,n$17:NSObject<OS_dispatch_queue>*,(_fun_objc_blockDispatchEx.dispatch_after_example_3):_fn_(*)) [line 46, column 3]\n " shape="box"]
"dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_4" -> "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_3" ; "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_4" -> "dispatch_after_example#DispatchEx#class.1d25856bd99eb1ef683c8f65ff46d05d_3" ;
@ -120,7 +120,7 @@ digraph cfg {
"dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_3" -> "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_2" ; "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_3" -> "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_2" ;
"dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_4" [label="4: Call _fun_dispatch_async \n n$9=_fun_dispatch_get_global_queue(0:long,(unsigned long)0:unsigned long) [line 36, column 18]\n n$13=_fun_dispatch_async(n$9:NSObject*,(_fun_objc_blockDispatchEx.dispatch_async_example_2):_fn_(*)) [line 36, column 3]\n " shape="box"] "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_4" [label="4: Call _fun_dispatch_async \n n$9=_fun_dispatch_get_global_queue(0:long,(unsigned long)0:unsigned long) [line 36, column 18]\n n$13=_fun_dispatch_async(n$9:NSObject<OS_dispatch_queue>*,(_fun_objc_blockDispatchEx.dispatch_async_example_2):_fn_(*)) [line 36, column 3]\n " shape="box"]
"dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_4" -> "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_3" ; "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_4" -> "dispatch_async_example#DispatchEx#class.5c5d7347be2a9654ad7e32514189fe54_3" ;
@ -139,7 +139,7 @@ digraph cfg {
"dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_3" -> "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_2" ; "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_3" -> "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_2" ;
"dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_4" [label="4: Call _fun_dispatch_barrier_async \n n$38=_fun_dispatch_get_main_queue() [line 75, column 26]\n n$42=_fun_dispatch_barrier_async(n$38:NSObject*,(_fun_objc_blockDispatchEx.dispatch_barrier_example_6):_fn_(*)) [line 75, column 3]\n " shape="box"] "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_4" [label="4: Call _fun_dispatch_barrier_async \n n$38=_fun_dispatch_get_main_queue() [line 75, column 26]\n n$42=_fun_dispatch_barrier_async(n$38:NSObject<OS_dispatch_queue>*,(_fun_objc_blockDispatchEx.dispatch_barrier_example_6):_fn_(*)) [line 75, column 3]\n " shape="box"]
"dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_4" -> "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_3" ; "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_4" -> "dispatch_barrier_example#DispatchEx#class.a541a40f2f04e29019c58e563f7544d8_3" ;
@ -158,7 +158,7 @@ digraph cfg {
"dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_3" -> "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_2" ; "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_3" -> "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_2" ;
"dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_4" [label="4: Call _fun_dispatch_group_async \n n$24=_fun_dispatch_get_main_queue() [line 57, column 30]\n n$28=_fun_dispatch_group_async(null:NSObject*,n$24:NSObject*,(_fun_objc_blockDispatchEx.dispatch_group_example_4):_fn_(*)) [line 57, column 3]\n " shape="box"] "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_4" [label="4: Call _fun_dispatch_group_async \n n$24=_fun_dispatch_get_main_queue() [line 57, column 30]\n n$28=_fun_dispatch_group_async(null:NSObject<OS_dispatch_group>*,n$24:NSObject<OS_dispatch_queue>*,(_fun_objc_blockDispatchEx.dispatch_group_example_4):_fn_(*)) [line 57, column 3]\n " shape="box"]
"dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_4" -> "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_3" ; "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_4" -> "dispatch_group_example#DispatchEx#class.f420a75c58eda6d3f0e5e05fadabfc18_3" ;
@ -177,7 +177,7 @@ digraph cfg {
"dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_3" -> "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_2" ; "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_3" -> "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_2" ;
"dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_4" [label="4: Call _fun_dispatch_group_async \n n$31=_fun_dispatch_get_main_queue() [line 66, column 30]\n n$35=_fun_dispatch_group_async(null:NSObject*,n$31:NSObject*,(_fun_objc_blockDispatchEx.dispatch_group_notify_example_5):_fn_(*)) [line 66, column 3]\n " shape="box"] "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_4" [label="4: Call _fun_dispatch_group_async \n n$31=_fun_dispatch_get_main_queue() [line 66, column 30]\n n$35=_fun_dispatch_group_async(null:NSObject<OS_dispatch_group>*,n$31:NSObject<OS_dispatch_queue>*,(_fun_objc_blockDispatchEx.dispatch_group_notify_example_5):_fn_(*)) [line 66, column 3]\n " shape="box"]
"dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_4" -> "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_3" ; "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_4" -> "dispatch_group_notify_example#DispatchEx#class.f5cf54b07621c319cf7ead3b217760ed_3" ;

@ -48,7 +48,7 @@ digraph cfg {
"setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_2" [label="2: Exit ArcA.setSon: \n " color=yellow style=filled] "setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_2" [label="2: Exit ArcA.setSon: \n " color=yellow style=filled]
"setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_3" [label="3: BinaryOperatorStmt: Node \n n$3=*&self:ArcA* [line 14, column 17]\n n$4=*&son:ArcA* [line 14, column 17]\n *n$3._son:ArcA*=n$4 [line 14, column 17]\n " shape="box"] "setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_3" [label="3: BinaryOperatorStmt: Node \n n$5=*&self:ArcA* [line 14, column 17]\n n$6=*&son:ArcA* [line 14, column 17]\n *n$5._son:ArcA*=n$6 [line 14, column 17]\n " shape="box"]
"setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_3" -> "setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_2" ; "setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_3" -> "setSon:#ArcA(class ArcA)#instance.baae73471012ee089a7558f57ddd56fe_2" ;
@ -59,7 +59,7 @@ digraph cfg {
"son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_2" [label="2: Exit ArcA.son \n " color=yellow style=filled] "son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_2" [label="2: Exit ArcA.son \n " color=yellow style=filled]
"son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_3" [label="3: BinaryOperatorStmt: Node \n n$5=*&self:ArcA* [line 14, column 17]\n n$6=*n$5._son:ArcA* [line 14, column 17]\n *&return:ArcA*=n$6 [line 14, column 17]\n " shape="box"] "son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_3" [label="3: BinaryOperatorStmt: Node \n n$3=*&self:ArcA* [line 14, column 17]\n n$4=*n$3._son:ArcA* [line 14, column 17]\n *&return:ArcA*=n$4 [line 14, column 17]\n " shape="box"]
"son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_3" -> "son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_2" ; "son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_3" -> "son#ArcA#instance.eb40da6c5ac3fdfdee0ebe6b666b1ea5_2" ;

@ -70,7 +70,7 @@ digraph cfg {
"name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_2" [label="2: Exit NonnullC.name \n " color=yellow style=filled] "name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_2" [label="2: Exit NonnullC.name \n " color=yellow style=filled]
"name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_3" [label="3: BinaryOperatorStmt: Node \n n$5=*&self:NonnullC* [line 30, column 36]\n n$6=*n$5._name:NSString* [line 30, column 36]\n *&return:NSString*=n$6 [line 30, column 36]\n " shape="box"] "name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_3" [label="3: BinaryOperatorStmt: Node \n n$3=*&self:NonnullC* [line 30, column 36]\n n$4=*n$3._name:NSString* [line 30, column 36]\n *&return:NSString*=n$4 [line 30, column 36]\n " shape="box"]
"name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_3" -> "name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_2" ; "name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_3" -> "name#NonnullC#instance.9c59c8694c0f7942ace24d4346f9a7cd_2" ;
@ -81,7 +81,7 @@ digraph cfg {
"setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_2" [label="2: Exit NonnullC.setName: \n " color=yellow style=filled] "setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_2" [label="2: Exit NonnullC.setName: \n " color=yellow style=filled]
"setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_3" [label="3: BinaryOperatorStmt: Node \n n$3=*&self:NonnullC* [line 30, column 36]\n n$4=*&name:NSString* [line 30, column 36]\n *n$3._name:NSString*=n$4 [line 30, column 36]\n " shape="box"] "setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_3" [label="3: BinaryOperatorStmt: Node \n n$5=*&self:NonnullC* [line 30, column 36]\n n$6=*&name:NSString* [line 30, column 36]\n *n$5._name:NSString*=n$6 [line 30, column 36]\n " shape="box"]
"setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_3" -> "setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_2" ; "setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_3" -> "setName:#NonnullC(class NSString)#instance.06c11492d4403b7a142558aeec6ac42a_2" ;

@ -30,7 +30,7 @@ digraph cfg {
"child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_2" [label="2: Exit PropertyA.child \n " color=yellow style=filled] "child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_2" [label="2: Exit PropertyA.child \n " color=yellow style=filled]
"child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_3" [label="3: BinaryOperatorStmt: Node \n n$15=*&self:PropertyA* [line 12, column 39]\n n$16=*n$15._child:PropertyA* [line 12, column 39]\n *&return:PropertyA*=n$16 [line 12, column 39]\n " shape="box"] "child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_3" [label="3: BinaryOperatorStmt: Node \n n$13=*&self:PropertyA* [line 12, column 39]\n n$14=*n$13._child:PropertyA* [line 12, column 39]\n *&return:PropertyA*=n$14 [line 12, column 39]\n " shape="box"]
"child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_3" -> "child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_2" ; "child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_3" -> "child#PropertyA#instance.6f8ba5a5a49be48cc5dabe234a5b1918_2" ;
@ -103,7 +103,7 @@ digraph cfg {
"last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_2" [label="2: Exit PropertyA.last_name \n " color=yellow style=filled] "last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_2" [label="2: Exit PropertyA.last_name \n " color=yellow style=filled]
"last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_3" [label="3: BinaryOperatorStmt: Node \n n$13=*&self:PropertyA* [line 16, column 52]\n n$14=*n$13._last_name:PropertyA* [line 16, column 52]\n *&return:PropertyA*=n$14 [line 16, column 52]\n " shape="box"] "last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_3" [label="3: BinaryOperatorStmt: Node \n n$19=*&self:PropertyA* [line 16, column 52]\n n$20=*n$19._last_name:PropertyA* [line 16, column 52]\n *&return:PropertyA*=n$20 [line 16, column 52]\n " shape="box"]
"last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_3" -> "last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_2" ; "last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_3" -> "last_name#PropertyA#instance.1ce5ad70e2d4c718c3a98ccc959a3bc9_2" ;
@ -114,7 +114,7 @@ digraph cfg {
"name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_2" [label="2: Exit PropertyA.name \n " color=yellow style=filled] "name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_2" [label="2: Exit PropertyA.name \n " color=yellow style=filled]
"name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_3" [label="3: BinaryOperatorStmt: Node \n n$19=*&self:PropertyA* [line 14, column 41]\n n$20=*n$19._name:PropertyA* [line 14, column 41]\n *&return:PropertyA*=n$20 [line 14, column 41]\n " shape="box"] "name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_3" [label="3: BinaryOperatorStmt: Node \n n$11=*&self:PropertyA* [line 14, column 41]\n n$12=*n$11._name:PropertyA* [line 14, column 41]\n *&return:PropertyA*=n$12 [line 14, column 41]\n " shape="box"]
"name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_3" -> "name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_2" ; "name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_3" -> "name#PropertyA#instance.c1cdbf324fa14cda26c4633e95fc7667_2" ;
@ -125,7 +125,7 @@ digraph cfg {
"setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_2" [label="2: Exit PropertyA.setChild: \n " color=yellow style=filled] "setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_2" [label="2: Exit PropertyA.setChild: \n " color=yellow style=filled]
"setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_3" [label="3: BinaryOperatorStmt: Node \n n$9=*&self:PropertyA* [line 12, column 39]\n n$10=*&child:PropertyA* [line 12, column 39]\n *n$9._child:PropertyA*=n$10 [line 12, column 39]\n " shape="box"] "setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_3" [label="3: BinaryOperatorStmt: Node \n n$17=*&self:PropertyA* [line 12, column 39]\n n$18=*&child:PropertyA* [line 12, column 39]\n *n$17._child:PropertyA*=n$18 [line 12, column 39]\n " shape="box"]
"setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_3" -> "setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_2" ; "setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_3" -> "setChild:#PropertyA(class PropertyA)#instance.2830b91fc93649a2fb3b313489bf5461_2" ;
@ -136,7 +136,7 @@ digraph cfg {
"setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_2" [label="2: Exit PropertyA.setLast_name: \n " color=yellow style=filled] "setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_2" [label="2: Exit PropertyA.setLast_name: \n " color=yellow style=filled]
"setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_3" [label="3: BinaryOperatorStmt: Node \n n$11=*&self:PropertyA* [line 16, column 52]\n n$12=*&last_name:PropertyA* [line 16, column 52]\n *n$11._last_name:PropertyA*=n$12 [line 16, column 52]\n " shape="box"] "setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_3" [label="3: BinaryOperatorStmt: Node \n n$15=*&self:PropertyA* [line 16, column 52]\n n$16=*&last_name:PropertyA* [line 16, column 52]\n *n$15._last_name:PropertyA*=n$16 [line 16, column 52]\n " shape="box"]
"setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_3" -> "setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_2" ; "setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_3" -> "setLast_name:#PropertyA(class PropertyA)#instance.47d6f73ea37f95beeca8ce7a0352c15f_2" ;
@ -147,7 +147,7 @@ digraph cfg {
"setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_2" [label="2: Exit PropertyA.setName: \n " color=yellow style=filled] "setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_2" [label="2: Exit PropertyA.setName: \n " color=yellow style=filled]
"setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_3" [label="3: BinaryOperatorStmt: Node \n n$17=*&self:PropertyA* [line 14, column 41]\n n$18=*&name:PropertyA* [line 14, column 41]\n *n$17._name:PropertyA*=n$18 [line 14, column 41]\n " shape="box"] "setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_3" [label="3: BinaryOperatorStmt: Node \n n$9=*&self:PropertyA* [line 14, column 41]\n n$10=*&name:PropertyA* [line 14, column 41]\n *n$9._name:PropertyA*=n$10 [line 14, column 41]\n " shape="box"]
"setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_3" -> "setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_2" ; "setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_3" -> "setName:#PropertyA(class PropertyA)#instance.530a6c9eaa83786feeaf3a50fc2cd0e6_2" ;

Loading…
Cancel
Save