diff --git a/infer/src/clang/cEnum_decl.ml b/infer/src/clang/cEnum_decl.ml index 3dec73c5e..42d134cb9 100644 --- a/infer/src/clang/cEnum_decl.ml +++ b/infer/src/clang/cEnum_decl.ml @@ -47,7 +47,7 @@ let rec get_enum_constants context decl_list v = (Mangled.from_string name, const) :: get_enum_constants context decl_list' v) | _ -> assert false -let enum_decl name tenv cfg cg namespace decl_list opt_type = +let enum_decl name tenv cfg cg namespace pointer decl_list opt_type = Printing.log_out "ADDING: EnumDecl '%s'\n" name; let context' = CContext.create_context tenv cg cfg !global_procdesc namespace CContext.ContextNoCls @@ -57,7 +57,8 @@ let enum_decl name tenv cfg cg namespace decl_list opt_type = | `Type s -> s | `NoType -> assert false) in (* Here we could give "enum "^name but I want to check that this the type is always defined *) - let typename = Sil.TN_enum (Mangled.from_string name) in + let typename = CTypes.mk_enumname name in let typ = Sil.Tenum enum_constants in + Ast_utils.update_sil_types_map pointer typ; Printing.log_out " TN_typename('%s')\n" (Sil.typename_to_string typename); Sil.tenv_add tenv typename typ diff --git a/infer/src/clang/cEnum_decl.mli b/infer/src/clang/cEnum_decl.mli index fe8a24795..f744fe347 100644 --- a/infer/src/clang/cEnum_decl.mli +++ b/infer/src/clang/cEnum_decl.mli @@ -10,5 +10,5 @@ (** Translate an enumeration declaration by adding it to the tenv and *) (** translating the code and adding it to a fake procdesc *) -val enum_decl : string -> Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> +val enum_decl : string -> Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.pointer -> Clang_ast_t.decl list -> Clang_ast_t.opt_type -> unit diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index 1972dec31..ec69644d6 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -34,9 +34,7 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = | FunctionDecl(di, name_info, qt, fdecl_info) -> CMethod_declImpl.function_decl tenv cfg cg namespace dec None | TypedefDecl (decl_info, name_info, opt_type, _, typedef_decl_info) -> - let name = name_info.Clang_ast_t.ni_name in - CTypes_decl.do_typedef_declaration tenv namespace - decl_info name opt_type typedef_decl_info + Printing.log_out "%s" "Skipping typedef declaration. Will expand the type in its occurrences." (* Currently C/C++ record decl treated in the same way *) | CXXRecordDecl (_, _, _, _, decl_list, _, _, _) | RecordDecl (_, _, _, _, decl_list, _, _) -> @@ -50,10 +48,10 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = let name = name_info.Clang_ast_t.ni_name in CVar_decl.global_var_decl tenv namespace decl_info name t - | ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, obj_c_interface_decl_info) -> + | ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, oi_decl_info) -> let name = name_info.Clang_ast_t.ni_name in let curr_class = - ObjcInterface_decl.interface_declaration tenv name decl_list obj_c_interface_decl_info in + ObjcInterface_decl.interface_declaration tenv decl_info name decl_list oi_decl_info in CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list | ObjCProtocolDecl(decl_info, name_info, decl_list, decl_context_info, obj_c_protocol_decl_info) -> @@ -85,18 +83,18 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = | Some ptr -> Ast_utils.get_decl ptr | None -> Some parent_dec in (match class_decl with - | Some CXXRecordDecl(_, _, opt_type, _, _, _, _, _) -> - let class_name = CTypes_decl.get_record_name opt_type in + | Some CXXRecordDecl(_, name_info, opt_type, _, _, _, _, _) -> + let class_name = CTypes_decl.get_record_name opt_type name_info in let curr_class = CContext.ContextCls(class_name, None, []) in if !CFrontend_config.testing_mode then CMethod_declImpl.process_methods tenv cg cfg curr_class namespace [dec] | Some dec -> Printing.log_stats "Methods of %s skipped\n" (Ast_utils.string_of_decl dec) | None -> ()) - | EnumDecl(decl_info, name_info, opt_type, _, decl_list, decl_context_info, enum_decl_info) + | EnumDecl(decl_info, name_info, opt_type, pointer, decl_list, decl_context_info, enum_decl_info) when should_translate_enum -> let name = name_info.Clang_ast_t.ni_name in - CEnum_decl.enum_decl name tenv cfg cg namespace decl_list opt_type + CEnum_decl.enum_decl name tenv cfg cg namespace pointer decl_list opt_type | LinkageSpecDecl(decl_info, decl_list, decl_context_info) -> Printing.log_out "ADDING: LinkageSpecDecl decl list\n"; diff --git a/infer/src/clang/cFrontend_config.ml b/infer/src/clang/cFrontend_config.ml index ce7345db1..6a257237e 100644 --- a/infer/src/clang/cFrontend_config.ml +++ b/infer/src/clang/cFrontend_config.ml @@ -152,6 +152,7 @@ let generated_suffix = "*generated" let pointer_type_index = ref Clang_ast_main.PointerMap.empty +(* Map from type pointers or declaration pointers to sil types *) let sil_types_map = ref Clang_ast_main.PointerMap.empty let weak_attribute = "__weak" diff --git a/infer/src/clang/cFrontend_config.mli b/infer/src/clang/cFrontend_config.mli index 301694fd3..33c718d64 100644 --- a/infer/src/clang/cFrontend_config.mli +++ b/infer/src/clang/cFrontend_config.mli @@ -149,6 +149,7 @@ val generated_suffix : string val pointer_type_index : Clang_ast_t.c_type Clang_ast_main.PointerMap.t ref +(* Map from type pointers or declaration pointers to sil types *) val sil_types_map : (Sil.typ Clang_ast_main.PointerMap.t) ref val weak_attribute : string diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index 0638cdd63..c17cf9a28 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -147,6 +147,12 @@ struct | Some ns when ns ="" -> "" | Some ns -> ns^"::" + let get_qualifier_string name_info = + match name_info.Clang_ast_t.ni_qual_name with + | [] -> "" + | name :: qualifiers -> + list_fold_right (fun el res -> res ^ el ^ "::") qualifiers "" + let property_name property_impl_decl_info = let no_property_name = "WARNING_NO_PROPERTY_NAME" in match property_impl_decl_info.Clang_ast_t.opidi_property_decl with diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index dd42c5368..317efcbd2 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -79,6 +79,9 @@ sig val update_sil_types_map : Clang_ast_t.pointer -> Sil.typ -> unit + (** creates a string to append to a name from a list of qualifiers to a name *) + val get_qualifier_string : Clang_ast_t.named_decl_info -> string + end module General_utils : diff --git a/infer/src/clang/cTypes.ml b/infer/src/clang/cTypes.ml index a134cb044..dd211e8a1 100644 --- a/infer/src/clang/cTypes.ml +++ b/infer/src/clang/cTypes.ml @@ -113,17 +113,6 @@ let get_desugared_type t = | Some t' -> t' | _ -> assert false -(* Remove the work 'struct' from a type name. Used to avoid repetition when typename are constructed*) -(* E.g. 'struct struct s' *) -let cut_struct_union s = - Printing.log_out "Cutting '%s'@." s; - let buf = Str.split (Str.regexp "[ \t]+") s in - match buf with - | "struct":: l (*-> Printing.string_from_list l *) - | "class":: l - | "union":: l -> General_utils.string_from_list l - | _ -> s - let get_name_from_struct s = match s with | Sil.Tstruct(_, _, _, Some n, _, _, _) -> n @@ -155,7 +144,7 @@ let classname_of_type typ = | _ -> Printing.log_out "Classname of type cannot be extracted in type %s" (Sil.typ_to_string typ); - assert false + "undefined" let get_raw_qual_type_decl_ref_exp_info decl_ref_expr_info = match decl_ref_expr_info.Clang_ast_t.drti_decl_ref with diff --git a/infer/src/clang/cTypes.mli b/infer/src/clang/cTypes.mli index e42544e3b..08cd0cc68 100644 --- a/infer/src/clang/cTypes.mli +++ b/infer/src/clang/cTypes.mli @@ -31,10 +31,6 @@ val mk_enumname : string -> Sil.typename val get_name_from_struct: Sil.typ -> Mangled.t -(* Remove the work 'struct' from a type name. Used to avoid repetition when typename are constructed*) -(* E.g. 'struct struct s' *) -val cut_struct_union : string -> string - val remove_pointer_to_typ : Sil.typ -> Sil.typ val is_class : Sil.typ -> bool diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index 2aa73e6e4..64bc15b32 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -66,44 +66,29 @@ let add_predefined_types tenv = add_predefined_objc_types tenv; add_predefined_basic_types tenv -let rec search_for_named_type tenv typ = - let search typename = - match typename with - | Sil.TN_typedef name -> - (match Sil.tenv_lookup tenv typename with - | Some _ -> typename - | None -> - let pot_class_type = Sil.TN_csu (Sil.Class, name) in - match Sil.tenv_lookup tenv pot_class_type with - | Some _ -> pot_class_type - | None -> - let pot_protocol_type = Sil.TN_csu (Sil.Protocol, name) in - match Sil.tenv_lookup tenv pot_protocol_type with - | Some _ -> pot_protocol_type - | None -> - let pot_struct_type = Sil.TN_csu (Sil.Struct, name) in - match Sil.tenv_lookup tenv pot_struct_type with - | Some _ -> pot_struct_type - | None -> - let pot_union_type = Sil.TN_csu (Sil.Union, name) in - match Sil.tenv_lookup tenv pot_union_type with - | Some _ -> pot_union_type - | None -> raise Typename_not_found) - | _ -> typename in - match typ with - | Sil.Tvar typename -> Sil.Tvar (search typename) - | Sil.Tptr (typ, p) -> - Sil.Tptr (search_for_named_type tenv typ, p) - | _ -> typ - -let parse_func_type name func_type = None - +let create_csu opt_type = + match opt_type with + | `Type s -> + (let buf = Str.split (Str.regexp "[ \t]+") s in + match buf with + | "struct":: l ->Sil.Struct, General_utils.string_from_list l + | "class":: l -> Sil.Class, General_utils.string_from_list l + | "union":: l -> Sil.Union, General_utils.string_from_list l + | _ -> Sil.Struct, s) + | _ -> assert false (* We need to take the name out of the type as the struct can be anonymous*) -let get_record_name opt_type = match opt_type with - | `Type n' -> CTypes.cut_struct_union n' - | `NoType -> assert false +let get_record_name_csu opt_type name_info = + let name_str = name_info.Clang_ast_t.ni_name in + let csu, type_name = create_csu opt_type in + let prefix = Ast_utils.get_qualifier_string name_info in + let name = + if (String.length name_str = 0) then prefix ^ type_name else prefix ^ name_str in + csu, name + +let get_record_name opt_type name_info = + snd (get_record_name_csu opt_type name_info) let get_method_decls parent decl_list = let open Clang_ast_t in @@ -115,64 +100,31 @@ let get_method_decls parent decl_list = and traverse_decl_list parent decl_list = list_flatten (list_map (traverse_decl parent) decl_list) in traverse_decl_list parent decl_list -(*In case of typedef like *) -(* typedef struct { f1; f2; ... } s; *) -(* the AST-dump splits the typedef definition from the struct definition. *) -(* The type in the typedef "s" will be "s" and this become detached from the struct definition.*) -(* To avoid circular entry in tenv, we disambiguate this case.*) -(* We check if in tenv there is a "strucs s" defined and we make the type def "s" *) -(* point directly to "struct s" *) -let rec disambiguate_typedef tenv namespace t mn = - match t with - | Sil.Tvar(Sil.TN_typedef mn') -> - if (Mangled.equal mn mn') then - (* This will give a circularity in the definition of typedef in the tenv. *) - (* Eg. TN_typdef(mn) --> TN_typedef(mn). We need to break it*) - let tn = Sil.TN_csu(Sil.Struct, mn) in - (match Sil.tenv_lookup tenv tn with - | Some _ -> - (* There is a struct in tenv, so we make the typedef mn pointing to the struct*) - Printing.log_out " ...Found type TN_typdef('%s') " (Mangled.to_string mn); - Printing.log_out "in typedef of '%s'@." (Mangled.to_string mn); - Printing.log_out - "Avoid circular definition in tenv by pointing the typedef to struc TN_csu('%s')@." - (Mangled.to_string mn); - Sil.Tvar(tn) - | None -> - if add_late_defined_record tenv namespace tn then - disambiguate_typedef tenv namespace t mn - else t) - else t - | _ -> t - -and opt_type_to_sil_type tenv opt_type = - match opt_type with - | `Type(s) -> qual_type_to_sil_type tenv (Ast_expressions.create_qual_type s) - | `NoType -> Sil.Tvoid +let get_class_methods tenv class_name namespace decl_list = + let process_method_decl = function + | Clang_ast_t.CXXMethodDecl (decl_info, name_info, qual_type, function_decl_info) -> + let method_name = name_info.Clang_ast_t.ni_name in + Printing.log_out " ...Declaring method '%s'.\n" method_name; + let typ = CTypes.get_type qual_type in + let method_proc = General_utils.mk_procname_from_cpp_method class_name method_name typ in + Some method_proc + | _ -> None in + (* poor mans list_filter_map *) + list_flatten_options (list_map process_method_decl decl_list) -and do_typedef_declaration tenv namespace decl_info name opt_type typedef_decl_info = - if name = CFrontend_config.class_type || name = CFrontend_config.id_cl then () - else - let ns_suffix = Ast_utils.namespace_to_string namespace in - let name = ns_suffix^name in - let mn = Mangled.from_string name in - let typename = Sil.TN_typedef(mn) in - let t = opt_type_to_sil_type tenv opt_type in - (* check for ambiguities in typedef that may create circularities in tenv*) - let typ = disambiguate_typedef tenv namespace t mn in - Printing.log_out "ADDING: TypedefDecl for '%s'" name; - Printing.log_out " with type '%s'\n" (Sil.typ_to_string typ); - Printing.log_out " ...Adding entry to tenv with Typename TN_typedef = '%s'\n" - (Sil.typename_to_string typename); - Sil.tenv_add tenv typename typ +let add_struct_to_tenv tenv typ = + let csu = match typ with + | Sil.Tstruct(_, _, csu, _, _, _, _) -> csu + | _ -> assert false in + let mangled = CTypes.get_name_from_struct typ in + let typename = Sil.TN_csu(csu, mangled) in + Sil.tenv_add tenv typename typ -and get_struct_fields tenv record_name namespace decl_list = +let rec get_struct_fields tenv record_name namespace decl_list = let open Clang_ast_t in let do_one_decl decl = match decl with | FieldDecl (_, name_info, qual_type, _) -> - let field_name = name_info.Clang_ast_t.ni_name in - Printing.log_out " ...Defining field '%s'.\n" field_name; - let id = General_utils.mk_class_field_name record_name field_name in + let id = General_utils.mk_class_field_name record_name name_info.Clang_ast_t.ni_name in let typ = qual_type_to_sil_type tenv qual_type in let annotation_items = [] in (* For the moment we don't use them*) [(id, typ, annotation_items)] @@ -182,163 +134,46 @@ and get_struct_fields tenv record_name namespace decl_list = | _ -> [] in list_flatten (list_map do_one_decl decl_list) -and get_class_methods tenv class_name namespace decl_list = - let process_method_decl = function - | Clang_ast_t.CXXMethodDecl (decl_info, name_info, qual_type, function_decl_info) -> - let method_name = name_info.Clang_ast_t.ni_name in - Printing.log_out " ...Declaring method '%s'.\n" method_name; - let method_proc = General_utils.mk_procname_from_cpp_method class_name method_name (CTypes.get_type qual_type) in - Some method_proc - | _ -> None in - (* poor mans list_filter_map *) - list_flatten_options (list_map process_method_decl decl_list) +(* For a record declaration it returns/constructs the type *) +and get_declaration_type tenv namespace decl = + let open Clang_ast_t in + match decl with + | CXXRecordDecl (decl_info, name_info, opt_type, type_ptr, decl_list, _, record_decl_info, _) + | RecordDecl (decl_info, name_info, opt_type, type_ptr, decl_list, _, record_decl_info) -> + let csu, name = get_record_name_csu opt_type name_info in + let mangled_name = Mangled.from_string name in + let sil_typename = Sil.Tvar (Sil.TN_csu (csu, mangled_name)) in + (* temporarily saves the type name to avoid infinite loops in recursive types *) + Ast_utils.update_sil_types_map type_ptr sil_typename; + if not record_decl_info.Clang_ast_t.rdi_is_complete_definition then + Printing.log_err + " ...Warning, definition incomplete. The full definition will probably be later \n@."; + let non_static_fields = get_struct_fields tenv name namespace decl_list in + let non_static_fields' = if CTrans_models.is_objc_memory_model_controlled name then + General_utils.append_no_duplicates_fields [Sil.objc_ref_counter_field] non_static_fields + else non_static_fields in + let sorted_non_static_fields = CFrontend_utils.General_utils.sort_fields non_static_fields' in + let static_fields = [] in (* Warning for the moment we do not treat static field. *) + let methods = get_class_methods tenv name namespace decl_list in (* C++ methods only *) + let superclasses = [] in + let item_annotation = Sil.item_annotation_empty in (* No annotations for struts *) + let sil_type = Sil.Tstruct (sorted_non_static_fields, static_fields, csu, Some mangled_name, + superclasses, methods, item_annotation) in + Ast_utils.update_sil_types_map type_ptr sil_type; + sil_type + | _ -> assert false and add_types_from_decl_to_tenv tenv namespace decl = let typ = get_declaration_type tenv namespace decl in - let typ = expand_structured_type tenv typ in add_struct_to_tenv tenv typ; typ -(* For a record declaration it returns/constructs the type *) -and get_declaration_type tenv namespace decl = - let open Clang_ast_t in - let n, opt_type, decl_list = match decl with - | CXXRecordDecl (decl_info, name_info, opt_type, _, decl_list, _, record_decl_info, _) - | RecordDecl (decl_info, name_info, opt_type, _, decl_list, _, record_decl_info) -> - let ptr = decl_info.Clang_ast_t.di_pointer in - let name = name_info.Clang_ast_t.ni_name in - Printing.log_out "ADDING: RecordDecl for '%s'" name; - Printing.log_out " pointer= '%s'\n" ptr; - if not record_decl_info.Clang_ast_t.rdi_is_complete_definition then - Printing.log_err " ...Warning, definition incomplete. The full definition will probably be later \n@."; - name, opt_type, decl_list - | _ -> assert false in - - let ns_suffix = Ast_utils.namespace_to_string namespace in - let n = ns_suffix^n in - let name_str = get_record_name opt_type in - Printing.log_out "Record Declaration '%s' defined as struct\n" n; - let non_static_fields = get_struct_fields tenv name_str namespace decl_list in - let non_static_fields = if CTrans_models.is_objc_memory_model_controlled n then - General_utils.append_no_duplicates_fields [Sil.objc_ref_counter_field] non_static_fields - else non_static_fields in - let non_static_fields = CFrontend_utils.General_utils.sort_fields non_static_fields in - let static_fields = [] in (* Warning for the moment we do not treat static field. *) - let typ = (match opt_type with - | `Type s -> qual_type_to_sil_type tenv (Ast_expressions.create_qual_type s) - | _ -> assert false) in - let csu = (match typ with - | Sil.Tvar (Sil.TN_csu (csu, _)) -> csu - | _ -> Sil.Struct) in - let name = Some (Mangled.from_string name_str) in - let methods_list = get_class_methods tenv name_str namespace decl_list in (* C++ methods only *) - let superclass_list = [] in - let item_annotation = Sil.item_annotation_empty in (* No annotations for struts *) - Sil.Tstruct - (non_static_fields, static_fields, csu, name, superclass_list, methods_list, item_annotation) - -(* Look for a record definition that is defined after it is dereferenced. *) -(* It returns true if a new record definition has been added to tenv.*) -and add_late_defined_record tenv namespace typename = - Printing.log_out "!!!! Calling late-defined record '%s'\n" (Sil.typename_to_string typename) ; - match typename with - | Sil.TN_csu(Sil.Struct, name) | Sil.TN_csu(Sil.Union, name) -> - let open Clang_ast_t in - let rec scan decls = - match decls with - | [] -> false - | (CXXRecordDecl (_, _, opt_type, _, _, _, record_decl_info, _) as d) :: decls' - | (RecordDecl (_, _, opt_type, _, _, _, record_decl_info) as d) :: decls' -> - (match opt_type with - | `Type t -> - (* the string t contains the name of the type preceded by the word struct. *) - let t_no_struct = CTypes.cut_struct_union t in - let pot_struct_type = Sil.TN_csu (Sil.Struct, (Mangled.from_string t_no_struct)) in - let pot_union_type = Sil.TN_csu (Sil.Union, (Mangled.from_string t_no_struct)) in - if (Sil.typename_equal typename pot_struct_type || - Sil.typename_equal typename pot_union_type) && - record_decl_info.Clang_ast_t.rdi_is_complete_definition then ( - Printing.log_out "!!!! Adding late-defined record '%s'\n" t; - ignore (add_types_from_decl_to_tenv tenv namespace d); - true) - else scan decls' - | _ -> scan decls') - | LinkageSpecDecl(_, decl_list', _):: decls' -> scan (decl_list'@decls') - | _:: decls' -> scan decls' in - scan !CFrontend_config.global_translation_unit_decls - | _ -> false - -(* Look for a typedef definition that is defined after it is used. *) -(* It returns true if a new typedef definition has been added to tenv.*) -and add_late_defined_typedef tenv namespace typename = - Printing.log_out "Calling late-defined typedef '%s'\n" (Sil.typename_to_string typename); - match typename with - | Sil.TN_typedef name -> - let rec scan decls = - let open Clang_ast_t in - match decls with - | [] -> false - | TypedefDecl (decl_info, name_info, opt_type, _, tdi) :: decls' -> - let name' = name_info.Clang_ast_t.ni_name in - (match opt_type with - | `Type t -> - if (Mangled.to_string name) = name' then ( - Printing.log_out "!!!! Adding late-defined typedef '%s'\n" t; - do_typedef_declaration tenv namespace decl_info name' opt_type tdi; - true) - else scan decls' - | _ -> scan decls') - | LinkageSpecDecl(_, decl_list', _):: decls' -> scan (decl_list'@decls') - | _:: decls' -> scan decls' in - scan !CFrontend_config.global_translation_unit_decls - | _ -> false - -(* Expand a named type Tvar if it has a definition in tenv. This is used for Tenum, Tstruct, etc. *) -and expand_structured_type tenv typ = - match typ with - | Sil.Tvar tn -> - (match Sil.tenv_lookup tenv tn with - | Some t -> - Printing.log_out - " Type expanded with type '%s' found in tenv@." (Sil.typ_to_string t); - if Sil.typ_equal t typ then - typ - else expand_structured_type tenv t - | None -> if (add_late_defined_record tenv None tn || - add_late_defined_typedef tenv None tn) then - expand_structured_type tenv typ - else typ) - | Sil.Tptr(t, _) -> typ (*do not expand types under pointers *) - | _ -> typ - -and add_struct_to_tenv tenv typ = - let typ = expand_structured_type tenv typ in - let csu = match typ with - | Sil.Tstruct(_, _, csu, _, _, _, _) -> csu - | _ -> assert false in - let mangled = CTypes.get_name_from_struct typ in - let typename = Sil.TN_csu(csu, mangled) in - Printing.log_out " >>>Adding struct to tenv mangled='%s'\n" (Mangled.to_string mangled); - Printing.log_out " >>>Adding struct to tenv typ='%s'\n" (Sil.typ_to_string typ); - Printing.log_out " >>>with Key Typename TN_csu('%s')\n" (Sil.typename_to_string typename); - Printing.log_out " >>>Adding entry to tenv ('%s'," (Sil.typename_to_string typename); - Printing.log_out "'%s')\n" (Sil.typ_to_string typ); - Sil.tenv_add tenv typename typ; - Printing.log_out " >>>Verifying that Typename TN_csu('%s') is in tenv\n" - (Sil.typename_to_string typename); - (match Sil.tenv_lookup tenv typename with - | Some t -> Printing.log_out " >>>OK. Found typ='%s'\n" (Sil.typ_to_string t) - | None -> Printing.log_out " >>>NOT Found!!\n") - -(* Translate a qual_type from clang to sil type. *) and qual_type_to_sil_type tenv qt = CType_to_sil_type.qual_type_to_sil_type add_types_from_decl_to_tenv tenv qt -and qual_type_to_sil_type_np tenv qt = - qual_type_to_sil_type tenv qt -and type_name_to_sil_type tenv name = - qual_type_to_sil_type tenv (Ast_expressions.create_qual_type name) +let type_name_to_sil_type tenv name = + qual_type_to_sil_type tenv (Ast_expressions.create_class_type name) let get_type_from_expr_info ei tenv = let qt = ei.Clang_ast_t.ei_qual_type in @@ -364,4 +199,4 @@ let extract_sil_type_from_stmt tenv s = let get_type_curr_class tenv curr_class_opt = let name = CContext.get_curr_class_name curr_class_opt in let typ = Sil.Tvar (Sil.TN_csu (Sil.Class, (Mangled.from_string name))) in - expand_structured_type tenv typ + CTypes.expand_structured_type tenv typ diff --git a/infer/src/clang/cTypes_decl.mli b/infer/src/clang/cTypes_decl.mli index 47b2c1ef6..6741b8857 100644 --- a/infer/src/clang/cTypes_decl.mli +++ b/infer/src/clang/cTypes_decl.mli @@ -13,25 +13,18 @@ val get_declaration_type : Sil.tenv -> string option -> Clang_ast_t.decl -> Sil. val add_struct_to_tenv : Sil.tenv -> Sil.typ -> unit -val get_record_name : Clang_ast_t.opt_type -> string +val get_record_name : Clang_ast_t.opt_type -> Clang_ast_t.named_decl_info -> string val get_method_decls : Clang_ast_t.decl -> Clang_ast_t.decl list -> (Clang_ast_t.decl * Clang_ast_t.decl) list -val do_typedef_declaration : Sil.tenv -> string option -> Clang_ast_t.decl_info -> string -> - Clang_ast_t.opt_type -> Clang_ast_t.typedef_decl_info -> unit - val add_types_from_decl_to_tenv : Sil.tenv -> string option -> Clang_ast_t.decl -> Sil.typ -val parse_func_type : string -> string -> (Sil.typ * Sil.typ list) option - (* Adds the predefined types objc_class which is a struct, *) (* and Class, which is a pointer to objc_class. *) val add_predefined_types : Sil.tenv -> unit val qual_type_to_sil_type : Sil.tenv -> Clang_ast_t.qual_type -> Sil.typ -val qual_type_to_sil_type_np : Sil.tenv -> Clang_ast_t.qual_type -> Sil.typ - val class_from_pointer_type : Sil.tenv -> Clang_ast_t.qual_type -> string val get_class_type_np : Sil.tenv -> Clang_ast_t.expr_info -> @@ -41,8 +34,6 @@ val extract_sil_type_from_stmt : Sil.tenv -> Clang_ast_t.stmt -> Sil.typ val get_type_curr_class : Sil.tenv -> CContext.curr_class -> Sil.typ -val expand_structured_type : Sil.tenv -> Sil.typ -> Sil.typ - val get_type_from_expr_info : Clang_ast_t.expr_info -> Sil.tenv -> Sil.typ val type_name_to_sil_type : Sil.tenv -> string -> Sil.typ diff --git a/infer/src/clang/cVar_decl.ml b/infer/src/clang/cVar_decl.ml index cfa4fa10e..1def94643 100644 --- a/infer/src/clang/cVar_decl.ml +++ b/infer/src/clang/cVar_decl.ml @@ -162,8 +162,7 @@ and get_variables_decls context (decl_list : Clang_ast_t.decl list) : unit = let typ = CTypes_decl.get_declaration_type context.CContext.tenv context.CContext.namespace decl in CTypes_decl.add_struct_to_tenv context.CContext.tenv typ | TypedefDecl (decl_info, name_info, opt_type, _, typedef_decl_info) -> - CTypes_decl.do_typedef_declaration context.CContext.tenv context.CContext.namespace - decl_info name_info.Clang_ast_t.ni_name opt_type typedef_decl_info + Printing.log_out "%s" "Skipping typedef. Will expand the type in its occurrences." | StaticAssertDecl decl_info -> (* We do not treat Assertions. *) Printing.log_out "WARNING: When collecting variables, passing from StaticAssertDecl '%s'. Skipped.\n" diff --git a/infer/src/clang/objcInterface_decl.ml b/infer/src/clang/objcInterface_decl.ml index 80e15ed08..912da5ac0 100644 --- a/infer/src/clang/objcInterface_decl.ml +++ b/infer/src/clang/objcInterface_decl.ml @@ -90,7 +90,7 @@ let update_curr_class curr_class superclasses = | _ -> assert false (* Adds pairs (interface name, interface_type_info) to the global environment. *) -let add_class_to_tenv tenv class_name decl_list obj_c_interface_decl_info = +let add_class_to_tenv tenv decl_info class_name decl_list obj_c_interface_decl_info = Printing.log_out "ADDING: ObjCInterfaceDecl for '%s'\n" class_name; let interface_name = CTypes.mk_classname class_name in let curr_class, superclasses, fields = @@ -121,6 +121,7 @@ let add_class_to_tenv tenv class_name decl_list obj_c_interface_decl_info = Sil.Tstruct(fields, [], Sil.Class, Some (Mangled.from_string class_name), superclasses, methods, objc_class_annotation) in Sil.tenv_add tenv interface_name interface_type_info; + Ast_utils.update_sil_types_map decl_info.Clang_ast_t.di_pointer (Sil.Tvar interface_name); Printing.log_out " >>>Verifying that Typename '%s' is in tenv\n" (Sil.typename_to_string interface_name); (match Sil.tenv_lookup tenv interface_name with @@ -139,8 +140,8 @@ let add_missing_methods tenv class_name decl_list curr_class = | _ -> () (* Interface_type_info has the name of instance variables and the name of methods. *) -let interface_declaration tenv class_name decl_list obj_c_interface_decl_info = - add_class_to_tenv tenv class_name decl_list obj_c_interface_decl_info +let interface_declaration tenv decl_info class_name decl_list obj_c_interface_decl_info = + add_class_to_tenv tenv decl_info class_name decl_list obj_c_interface_decl_info (* Translate the methods defined in the implementation.*) let interface_impl_declaration tenv class_name decl_list idi = @@ -167,12 +168,13 @@ let lookup_late_defined_interface tenv cname = :: decls' when (Mangled.from_string name_info.Clang_ast_t.ni_name) = cname -> scan decls' - | ObjCInterfaceDecl (decl_info, name_info, decl_list, decl_context_info, obj_c_interface_decl_info) + | ObjCInterfaceDecl (decl_info, name_info, decl_list, decl_context_info, oi_decl_info) :: decls' when (Mangled.from_string name_info.Clang_ast_t.ni_name) = cname -> (* Assumption: here we assume that the first interface declaration with non empty set of fields is the *) (* correct one. So we stop. *) - ignore (interface_declaration tenv name_info.Clang_ast_t.ni_name decl_list obj_c_interface_decl_info) + let name = name_info.Clang_ast_t.ni_name in + ignore (interface_declaration tenv decl_info name decl_list oi_decl_info) | _:: decls' -> scan decls' in scan !CFrontend_config.global_translation_unit_decls diff --git a/infer/src/clang/objcInterface_decl.mli b/infer/src/clang/objcInterface_decl.mli index 6dde20ed6..a9f3e9017 100644 --- a/infer/src/clang/objcInterface_decl.mli +++ b/infer/src/clang/objcInterface_decl.mli @@ -11,7 +11,7 @@ (** is saved in the tenv as a struct with the corresponding fields, potential superclass and *) (** list of defined methods *) -val interface_declaration : Sil.tenv -> string -> Clang_ast_t.decl list -> +val interface_declaration : Sil.tenv -> Clang_ast_t.decl_info -> string -> Clang_ast_t.decl list -> Clang_ast_t.obj_c_interface_decl_info -> CContext.curr_class val find_field : Sil.tenv -> string -> Sil.typ option -> bool -> diff --git a/infer/tests/codetoanalyze/c/frontend/initialization/struct_initlistexpr.dot b/infer/tests/codetoanalyze/c/frontend/initialization/struct_initlistexpr.dot index c0394cd3a..5869ccb12 100644 --- a/infer/tests/codetoanalyze/c/frontend/initialization/struct_initlistexpr.dot +++ b/infer/tests/codetoanalyze/c/frontend/initialization/struct_initlistexpr.dot @@ -25,7 +25,7 @@ digraph iCFG { 8 [label="8: Exit test \n " color=yellow style=filled] -7 [label="7: Start test\nFormals: p:Point *\nLocals: \n DECLARE_LOCALS(&return); [line 23]\n NULLIFY(&p,false); [line 23]\n " color=yellow style=filled] +7 [label="7: Start test\nFormals: p:struct Point *\nLocals: \n DECLARE_LOCALS(&return); [line 23]\n NULLIFY(&p,false); [line 23]\n " color=yellow style=filled] 7 -> 10 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/types/methods.dot b/infer/tests/codetoanalyze/cpp/frontend/types/methods.dot index 907c36aef..9ee1390ec 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/types/methods.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/types/methods.dot @@ -32,7 +32,7 @@ digraph iCFG { 21 [label="21: Exit A_add \n " color=yellow style=filled] -20 [label="20: Start A_add\nFormals: this:struct A other:struct A &\nLocals: \n DECLARE_LOCALS(&return); [line 41]\n NULLIFY(&this,false); [line 41]\n NULLIFY(&other,false); [line 41]\n " color=yellow style=filled] +20 [label="20: Start A_add\nFormals: this:struct A other:struct A &\nLocals: \n DECLARE_LOCALS(&return); [line 41]\n NULLIFY(&other,false); [line 41]\n NULLIFY(&this,false); [line 41]\n " color=yellow style=filled] 20 -> 21 ; @@ -58,14 +58,14 @@ digraph iCFG { 14 [label="14: Exit A_fun \n " color=yellow style=filled] -13 [label="13: Start A_fun\nFormals: this:struct A a:int b:int \nLocals: c:int \n DECLARE_LOCALS(&return,&c); [line 30]\n NULLIFY(&this,false); [line 30]\n NULLIFY(&c,false); [line 30]\n " color=yellow style=filled] +13 [label="13: Start A_fun\nFormals: this:struct A a:int b:int \nLocals: c:int \n DECLARE_LOCALS(&return,&c); [line 30]\n NULLIFY(&c,false); [line 30]\n NULLIFY(&this,false); [line 30]\n " color=yellow style=filled] 13 -> 16 ; 12 [label="12: Exit A_fun \n " color=yellow style=filled] -11 [label="11: Start A_fun\nFormals: this:struct A a:int b:int c:int \nLocals: \n DECLARE_LOCALS(&return); [line 25]\n NULLIFY(&this,false); [line 25]\n NULLIFY(&a,false); [line 25]\n NULLIFY(&b,false); [line 25]\n NULLIFY(&c,false); [line 25]\n " color=yellow style=filled] +11 [label="11: Start A_fun\nFormals: this:struct A a:int b:int c:int \nLocals: \n DECLARE_LOCALS(&return); [line 25]\n NULLIFY(&a,false); [line 25]\n NULLIFY(&b,false); [line 25]\n NULLIFY(&c,false); [line 25]\n NULLIFY(&this,false); [line 25]\n " color=yellow style=filled] 11 -> 12 ; @@ -91,7 +91,7 @@ digraph iCFG { 5 [label="5: Exit A_def_in \n " color=yellow style=filled] -4 [label="4: Start A_def_in\nFormals: this:struct A \nLocals: c:int \n DECLARE_LOCALS(&return,&c); [line 17]\n NULLIFY(&this,false); [line 17]\n NULLIFY(&c,false); [line 17]\n " color=yellow style=filled] +4 [label="4: Start A_def_in\nFormals: this:struct A \nLocals: c:int \n DECLARE_LOCALS(&return,&c); [line 17]\n NULLIFY(&c,false); [line 17]\n NULLIFY(&this,false); [line 17]\n " color=yellow style=filled] 4 -> 7 ; diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakExample.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakExample.dot index ca4ff413b..e0a01004f 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakExample.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/MemoryLeakExample.dot @@ -141,7 +141,7 @@ digraph iCFG { 11 -> 13 ; -10 [label="10: DeclStmt \n n$13=*&self:class MemoryLeakExample * [line 31]\n n$12=_fun_MemoryLeakExample_backgroundCoveringView(n$13:class MemoryLeakExample *) virtual [line 31]\n n$11=_fun_UIView_bounds(n$12:class UIView *) virtual [line 31]\n n$14=_fun_CGPathCreateWithRect(n$11:struct CGRect ,0:CGAffineTransform *) [line 31]\n *&shadowPath:struct CGPath *=n$14 [line 31]\n REMOVE_TEMPS(n$11,n$12,n$13,n$14); [line 31]\n " shape="box"] +10 [label="10: DeclStmt \n n$13=*&self:class MemoryLeakExample * [line 31]\n n$12=_fun_MemoryLeakExample_backgroundCoveringView(n$13:class MemoryLeakExample *) virtual [line 31]\n n$11=_fun_UIView_bounds(n$12:class UIView *) virtual [line 31]\n n$14=_fun_CGPathCreateWithRect(n$11:struct CGRect ,0:struct CGAffineTransform *) [line 31]\n *&shadowPath:struct CGPath *=n$14 [line 31]\n REMOVE_TEMPS(n$11,n$12,n$13,n$14); [line 31]\n " shape="box"] 10 -> 9 ; @@ -160,7 +160,7 @@ digraph iCFG { 6 -> 5 ; -5 [label="5: DeclStmt \n n$3=*&attachmentContainerView:class UIView * [line 22]\n n$2=_fun_UIView_bounds(n$3:class UIView *) virtual [line 22]\n n$4=_fun_CGPathCreateWithRect(n$2:struct CGRect ,0:CGAffineTransform *) [line 22]\n *&shadowPath:struct CGPath *=n$4 [line 22]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 22]\n " shape="box"] +5 [label="5: DeclStmt \n n$3=*&attachmentContainerView:class UIView * [line 22]\n n$2=_fun_UIView_bounds(n$3:class UIView *) virtual [line 22]\n n$4=_fun_CGPathCreateWithRect(n$2:struct CGRect ,0:struct CGAffineTransform *) [line 22]\n *&shadowPath:struct CGPath *=n$4 [line 22]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 22]\n " shape="box"] 5 -> 4 ; diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/TollBridgeExample.dot b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/TollBridgeExample.dot index 4438f5365..ac027c260 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/TollBridgeExample.dot +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/TollBridgeExample.dot @@ -1,5 +1,5 @@ digraph iCFG { -19 [label="19: Return Stmt \n n$0=_fun___builtin___CFStringMakeConstantString(\"Icon\":char *) [line 43]\n n$1=_fun_CTFontCreateWithName(n$0:struct __CFString *,17.000000:double ,0:CGAffineTransform *) [line 43]\n n$2=_fun___objc_cast(n$1:void *,sizeof(void ):unsigned long ) [line 43]\n *&return:struct __CTFont *=n$2 [line 43]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] +19 [label="19: Return Stmt \n n$0=_fun___builtin___CFStringMakeConstantString(\"Icon\":char *) [line 43]\n n$1=_fun_CTFontCreateWithName(n$0:struct __CFString *,17.000000:double ,0:struct CGAffineTransform *) [line 43]\n n$2=_fun___objc_cast(n$1:void *,sizeof(void ):unsigned long ) [line 43]\n *&return:struct __CTFont *=n$2 [line 43]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] 19 -> 18 ; diff --git a/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot b/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot index ba08e3d0e..bf94345f4 100644 --- a/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot +++ b/infer/tests/codetoanalyze/objc/errors/npe/Nonnull_attribute_example.dot @@ -1,9 +1,9 @@ digraph iCFG { -20 [label="20: Call _fun___infer_assume \n n$1=*&callback:_fn_ (*) [line 46]\n n$2=_fun___infer_assume((n$1 != 0):_fn_ (*)) [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n " shape="box"] +20 [label="20: Call _fun___infer_assume \n n$1=*&callback:_fn_ (*) [line 46]\n _fun___infer_assume((n$1 != 0):_fn_ (*)) [line 46]\n REMOVE_TEMPS(n$1); [line 46]\n " shape="box"] 20 -> 19 ; -19 [label="19: Call n$0 \n n$0=*&callback:_fn_ (*) [line 47]\n n$0(0:class NSError *,0:id *) [line 47]\n REMOVE_TEMPS(n$0); [line 47]\n NULLIFY(&callback,false); [line 47]\n APPLY_ABSTRACTION; [line 47]\n " shape="box"] +19 [label="19: Call n$0 \n n$0=*&callback:_fn_ (*) [line 47]\n n$0(0:class NSError *,0:struct objc_object *) [line 47]\n REMOVE_TEMPS(n$0); [line 47]\n NULLIFY(&callback,false); [line 47]\n APPLY_ABSTRACTION; [line 47]\n " shape="box"] 19 -> 18 ; @@ -14,11 +14,11 @@ digraph iCFG { 17 -> 20 ; -16 [label="16: Call _fun___infer_assume \n n$13=*&name:class NSString * [line -1]\n n$14=_fun___infer_assume((n$13 != 0):class NSString *) [line -1]\n REMOVE_TEMPS(n$13,n$14); [line -1]\n " shape="box"] +16 [label="16: Call _fun___infer_assume \n n$12=*&name:class NSString * [line -1]\n _fun___infer_assume((n$12 != 0):class NSString *) [line -1]\n REMOVE_TEMPS(n$12); [line -1]\n " shape="box"] 16 -> 15 ; -15 [label="15: BinaryOperatorStmt: Assign \n n$10=*&self:class C * [line 31]\n n$12=*&name:class NSString * [line 31]\n n$11=_fun_NSString_copy(n$12:class NSString *) virtual [line 31]\n *n$10._name:class NSString *=n$11 [line 31]\n REMOVE_TEMPS(n$10,n$11,n$12); [line 31]\n NULLIFY(&name,false); [line 31]\n NULLIFY(&self,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] +15 [label="15: BinaryOperatorStmt: Assign \n n$9=*&self:class C * [line 31]\n n$11=*&name:class NSString * [line 31]\n n$10=_fun_NSString_copy(n$11:class NSString *) virtual [line 31]\n *n$9._name:class NSString *=n$10 [line 31]\n REMOVE_TEMPS(n$9,n$10,n$11); [line 31]\n NULLIFY(&name,false); [line 31]\n NULLIFY(&self,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] 15 -> 14 ; @@ -29,7 +29,7 @@ digraph iCFG { 13 -> 16 ; -12 [label="12: Return Stmt \n n$7=*&self:class C * [line 31]\n n$8=*n$7._name:class NSString * [line 31]\n *&return:class NSString *=n$8 [line 31]\n n$9=_fun___set_autorelease_attribute(n$8:class NSString *) [line 31]\n REMOVE_TEMPS(n$7,n$8,n$9); [line 31]\n NULLIFY(&self,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] +12 [label="12: Return Stmt \n n$6=*&self:class C * [line 31]\n n$7=*n$6._name:class NSString * [line 31]\n *&return:class NSString *=n$7 [line 31]\n n$8=_fun___set_autorelease_attribute(n$7:class NSString *) [line 31]\n REMOVE_TEMPS(n$6,n$7,n$8); [line 31]\n NULLIFY(&self,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] 12 -> 11 ; @@ -40,7 +40,7 @@ digraph iCFG { 10 -> 12 ; -9 [label="9: Call _fun___infer_assume \n n$5=*&a:class A * [line -1]\n n$6=_fun___infer_assume((n$5 != 0):class A *) [line -1]\n REMOVE_TEMPS(n$5,n$6); [line -1]\n " shape="box"] +9 [label="9: Call _fun___infer_assume \n n$5=*&a:class A * [line -1]\n _fun___infer_assume((n$5 != 0):class A *) [line -1]\n REMOVE_TEMPS(n$5); [line -1]\n " shape="box"] 9 -> 8 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot b/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot index 112040be3..93477ed93 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/block-it.dot @@ -1,21 +1,21 @@ digraph iCFG { -52 [label="52: DeclStmt \n n$47=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 30]\n n$45=_fun_NSArray_init(n$47:class NSArray *) virtual [line 30]\n *&a:class NSArray *=n$45 [line 30]\n REMOVE_TEMPS(n$45,n$47); [line 30]\n " shape="box"] +52 [label="52: DeclStmt \n n$44=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 30]\n n$42=_fun_NSArray_init(n$44:class NSArray *) virtual [line 30]\n *&a:class NSArray *=n$42 [line 30]\n REMOVE_TEMPS(n$42,n$44); [line 30]\n " shape="box"] 52 -> 51 ; -51 [label="51: DeclStmt \n n$44=*&a:class NSArray * [line 32]\n *&objects:class NSArray *=n$44 [line 32]\n REMOVE_TEMPS(n$44); [line 32]\n NULLIFY(&a,false); [line 32]\n " shape="box"] +51 [label="51: DeclStmt \n n$41=*&a:class NSArray * [line 32]\n *&objects:class NSArray *=n$41 [line 32]\n REMOVE_TEMPS(n$41); [line 32]\n NULLIFY(&a,false); [line 32]\n " shape="box"] 51 -> 44 ; -50 [label="50: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 40]\n n$42=*&stop:BOOL * [line 40]\n *n$42:_Bool =1 [line 40]\n REMOVE_TEMPS(n$42); [line 40]\n NULLIFY(&stop,false); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"] +50 [label="50: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 40]\n n$39=*&stop:_Bool * [line 40]\n *n$39:_Bool =1 [line 40]\n REMOVE_TEMPS(n$39); [line 40]\n NULLIFY(&stop,false); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"] 50 -> 47 ; -49 [label="49: Prune (false branch) \n n$41=*&ShouldStop:int [line 39]\n PRUNE((n$41 == 0), false); [line 39]\n REMOVE_TEMPS(n$41); [line 39]\n APPLY_ABSTRACTION; [line 39]\n " shape="invhouse"] +49 [label="49: Prune (false branch) \n n$38=*&ShouldStop:int [line 39]\n PRUNE((n$38 == 0), false); [line 39]\n REMOVE_TEMPS(n$38); [line 39]\n APPLY_ABSTRACTION; [line 39]\n " shape="invhouse"] 49 -> 47 ; -48 [label="48: Prune (true branch) \n n$41=*&ShouldStop:int [line 39]\n PRUNE((n$41 != 0), true); [line 39]\n REMOVE_TEMPS(n$41); [line 39]\n " shape="invhouse"] +48 [label="48: Prune (true branch) \n n$38=*&ShouldStop:int [line 39]\n PRUNE((n$38 != 0), true); [line 39]\n REMOVE_TEMPS(n$38); [line 39]\n " shape="invhouse"] 48 -> 50 ; @@ -26,40 +26,40 @@ digraph iCFG { 46 [label="46: Exit __objc_anonymous_block_MyBlock_array_trans______2 \n " color=yellow style=filled] -45 [label="45: Start __objc_anonymous_block_MyBlock_array_trans______2\nFormals: object:struct objc_object * idx:unsigned long stop:BOOL *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 35]\n NULLIFY(&idx,false); [line 35]\n NULLIFY(&object,false); [line 35]\n " color=yellow style=filled] +45 [label="45: Start __objc_anonymous_block_MyBlock_array_trans______2\nFormals: object:struct objc_object * idx:unsigned long stop:_Bool *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 35]\n NULLIFY(&idx,false); [line 35]\n NULLIFY(&object,false); [line 35]\n " color=yellow style=filled] 45 -> 48 ; 45 -> 49 ; -44 [label="44: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array_trans______2); [line 35]\n n$43=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array_trans______2 ):unsigned long ) [line 35]\n *&__objc_anonymous_block_MyBlock_array_trans______2:class __objc_anonymous_block_MyBlock_array_trans______2 =n$43 [line 35]\n *&enumerateObjectsUsingBlock:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array_trans______2) [line 35]\n REMOVE_TEMPS(n$43); [line 35]\n " shape="box"] +44 [label="44: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array_trans______2); [line 35]\n n$40=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array_trans______2 ):unsigned long ) [line 35]\n *&__objc_anonymous_block_MyBlock_array_trans______2:class __objc_anonymous_block_MyBlock_array_trans______2 =n$40 [line 35]\n *&enumerateObjectsUsingBlock:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array_trans______2) [line 35]\n REMOVE_TEMPS(n$40); [line 35]\n " shape="box"] 44 -> 43 ; -43 [label="43: DeclStmt \n n$40=_fun_malloc_no_fail(sizeof(_Bool ):_Bool ) [line 43]\n *&stop:BOOL *=n$40 [line 43]\n REMOVE_TEMPS(n$40); [line 43]\n " shape="box"] +43 [label="43: DeclStmt \n n$37=_fun_malloc_no_fail(sizeof(_Bool ):_Bool ) [line 43]\n *&stop:_Bool *=n$37 [line 43]\n REMOVE_TEMPS(n$37); [line 43]\n " shape="box"] 43 -> 42 ; -42 [label="42: BinaryOperatorStmt: Assign \n n$39=*&stop:BOOL * [line 44]\n *n$39:_Bool =0 [line 44]\n REMOVE_TEMPS(n$39); [line 44]\n " shape="box"] +42 [label="42: BinaryOperatorStmt: Assign \n n$36=*&stop:_Bool * [line 44]\n *n$36:_Bool =0 [line 44]\n REMOVE_TEMPS(n$36); [line 44]\n " shape="box"] 42 -> 31 ; -41 [label="41: DeclStmt \n n$37=*&objects:class NSArray * [line 49]\n n$38=*&idx:unsigned long [line 49]\n n$36=_fun_NSArray_objectAtIndexedSubscript:(n$37:class NSArray *,n$38:unsigned long ) virtual [line 49]\n *&object:struct objc_object *=n$36 [line 49]\n REMOVE_TEMPS(n$36,n$37,n$38); [line 49]\n " shape="box"] +41 [label="41: DeclStmt \n n$34=*&objects:class NSArray * [line 49]\n n$35=*&idx:unsigned long [line 49]\n n$33=_fun_NSArray_objectAtIndexedSubscript:(n$34:class NSArray *,n$35:unsigned long ) virtual [line 49]\n *&object:struct objc_object *=n$33 [line 49]\n REMOVE_TEMPS(n$33,n$34,n$35); [line 49]\n " shape="box"] 41 -> 40 ; -40 [label="40: Call n$32 \n n$32=*&enumerateObjectsUsingBlock:_fn_ (*) [line 50]\n n$33=*&object:struct objc_object * [line 50]\n n$34=*&idx:unsigned long [line 50]\n n$35=*&stop:BOOL * [line 50]\n n$32(n$33:struct objc_object *,n$34:unsigned long ,n$35:BOOL *) [line 50]\n REMOVE_TEMPS(n$32,n$33,n$34,n$35); [line 50]\n NULLIFY(&object,false); [line 50]\n " shape="box"] +40 [label="40: Call n$29 \n n$29=*&enumerateObjectsUsingBlock:_fn_ (*) [line 50]\n n$30=*&object:struct objc_object * [line 50]\n n$31=*&idx:unsigned long [line 50]\n n$32=*&stop:_Bool * [line 50]\n n$29(n$30:struct objc_object *,n$31:unsigned long ,n$32:_Bool *) [line 50]\n REMOVE_TEMPS(n$29,n$30,n$31,n$32); [line 50]\n NULLIFY(&object,false); [line 50]\n " shape="box"] 40 -> 37 ; -39 [label="39: Prune (false branch) \n PRUNE(((n$31 == 1) == 0), false); [line 51]\n REMOVE_TEMPS(n$30,n$31); [line 51]\n " shape="invhouse"] +39 [label="39: Prune (false branch) \n PRUNE(((n$28 == 1) == 0), false); [line 51]\n REMOVE_TEMPS(n$27,n$28); [line 51]\n " shape="invhouse"] 39 -> 36 ; -38 [label="38: Prune (true branch) \n PRUNE(((n$31 == 1) != 0), true); [line 51]\n REMOVE_TEMPS(n$30,n$31); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="invhouse"] +38 [label="38: Prune (true branch) \n PRUNE(((n$28 == 1) != 0), true); [line 51]\n REMOVE_TEMPS(n$27,n$28); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="invhouse"] 38 -> 29 ; -37 [label="37: BinaryOperatorStmt: EQ \n n$30=*&stop:BOOL * [line 51]\n n$31=*n$30:_Bool [line 51]\n " shape="box"] +37 [label="37: BinaryOperatorStmt: EQ \n n$27=*&stop:_Bool * [line 51]\n n$28=*n$27:_Bool [line 51]\n " shape="box"] 37 -> 38 ; @@ -68,20 +68,20 @@ digraph iCFG { 36 -> 32 ; -35 [label="35: Prune (false branch) \n PRUNE(((n$27 < n$28) == 0), false); [line 46]\n REMOVE_TEMPS(n$27,n$28,n$29); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="invhouse"] +35 [label="35: Prune (false branch) \n PRUNE(((n$24 < n$25) == 0), false); [line 46]\n REMOVE_TEMPS(n$24,n$25,n$26); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="invhouse"] 35 -> 29 ; -34 [label="34: Prune (true branch) \n PRUNE(((n$27 < n$28) != 0), true); [line 46]\n REMOVE_TEMPS(n$27,n$28,n$29); [line 46]\n " shape="invhouse"] +34 [label="34: Prune (true branch) \n PRUNE(((n$24 < n$25) != 0), true); [line 46]\n REMOVE_TEMPS(n$24,n$25,n$26); [line 46]\n " shape="invhouse"] 34 -> 41 ; -33 [label="33: BinaryOperatorStmt: LT \n n$27=*&idx:unsigned long [line 46]\n n$29=*&objects:class NSArray * [line 46]\n n$28=_fun_NSArray_count(n$29:class NSArray *) virtual [line 46]\n " shape="box"] +33 [label="33: BinaryOperatorStmt: LT \n n$24=*&idx:unsigned long [line 46]\n n$26=*&objects:class NSArray * [line 46]\n n$25=_fun_NSArray_count(n$26:class NSArray *) virtual [line 46]\n " shape="box"] 33 -> 34 ; 33 -> 35 ; -32 [label="32: UnaryOperator \n n$26=*&idx:unsigned long [line 46]\n *&idx:unsigned long =(n$26 + 1) [line 46]\n REMOVE_TEMPS(n$26); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] +32 [label="32: UnaryOperator \n n$23=*&idx:unsigned long [line 46]\n *&idx:unsigned long =(n$23 + 1) [line 46]\n REMOVE_TEMPS(n$23); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] 32 -> 30 ; @@ -93,34 +93,34 @@ digraph iCFG { 30 -> 33 ; -29 [label="29: Call _fun_free \n NULLIFY(&enumerateObjectsUsingBlock,false); [line 53]\n NULLIFY(&idx,false); [line 53]\n NULLIFY(&objects,false); [line 53]\n n$25=*&stop:BOOL * [line 53]\n _fun_free(n$25:void *) [line 53]\n REMOVE_TEMPS(n$25); [line 53]\n NULLIFY(&__objc_anonymous_block_MyBlock_array_trans______2,true); [line 53]\n NULLIFY(&stop,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] +29 [label="29: Call _fun_free \n NULLIFY(&enumerateObjectsUsingBlock,false); [line 53]\n NULLIFY(&idx,false); [line 53]\n NULLIFY(&objects,false); [line 53]\n n$22=*&stop:_Bool * [line 53]\n _fun_free(n$22:void *) [line 53]\n REMOVE_TEMPS(n$22); [line 53]\n NULLIFY(&__objc_anonymous_block_MyBlock_array_trans______2,true); [line 53]\n NULLIFY(&stop,false); [line 53]\n APPLY_ABSTRACTION; [line 53]\n " shape="box"] 29 -> 28 ; 28 [label="28: Exit MyBlock_array_trans \n " color=yellow style=filled] -27 [label="27: Start MyBlock_array_trans\nFormals: self:class MyBlock *\nLocals: a:class NSArray * objects:class NSArray * enumerateObjectsUsingBlock:_fn_ (*) stop:BOOL * idx:unsigned long object:struct objc_object * \n DECLARE_LOCALS(&return,&a,&objects,&enumerateObjectsUsingBlock,&stop,&idx,&object); [line 28]\n NULLIFY(&a,false); [line 28]\n NULLIFY(&enumerateObjectsUsingBlock,false); [line 28]\n NULLIFY(&idx,false); [line 28]\n NULLIFY(&object,false); [line 28]\n NULLIFY(&objects,false); [line 28]\n NULLIFY(&self,false); [line 28]\n NULLIFY(&stop,false); [line 28]\n " color=yellow style=filled] +27 [label="27: Start MyBlock_array_trans\nFormals: self:class MyBlock *\nLocals: a:class NSArray * objects:class NSArray * enumerateObjectsUsingBlock:_fn_ (*) stop:_Bool * idx:unsigned long object:struct objc_object * \n DECLARE_LOCALS(&return,&a,&objects,&enumerateObjectsUsingBlock,&stop,&idx,&object); [line 28]\n NULLIFY(&a,false); [line 28]\n NULLIFY(&enumerateObjectsUsingBlock,false); [line 28]\n NULLIFY(&idx,false); [line 28]\n NULLIFY(&object,false); [line 28]\n NULLIFY(&objects,false); [line 28]\n NULLIFY(&self,false); [line 28]\n NULLIFY(&stop,false); [line 28]\n " color=yellow style=filled] 27 -> 52 ; -26 [label="26: DeclStmt \n n$24=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 14]\n n$22=_fun_NSArray_init(n$24:class NSArray *) virtual [line 14]\n *&a:class NSArray *=n$22 [line 14]\n REMOVE_TEMPS(n$22,n$24); [line 14]\n " shape="box"] +26 [label="26: DeclStmt \n n$21=_fun___objc_alloc_no_fail(sizeof(class NSArray ):unsigned long ) [line 14]\n n$19=_fun_NSArray_init(n$21:class NSArray *) virtual [line 14]\n *&a:class NSArray *=n$19 [line 14]\n REMOVE_TEMPS(n$19,n$21); [line 14]\n " shape="box"] 26 -> 25 ; -25 [label="25: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_MyBlock_array______1); [line 15]\n DECLARE_LOCALS(&objects); [line 15]\n DECLARE_LOCALS(&stop); [line 15]\n DECLARE_LOCALS(&idx); [line 15]\n DECLARE_LOCALS(&object); [line 15]\n n$21=*&a:class NSArray * [line 15]\n *&objects:class NSArray *=n$21 [line 15]\n REMOVE_TEMPS(n$21); [line 15]\n NULLIFY(&a,false); [line 15]\n " shape="box"] +25 [label="25: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_MyBlock_array______1); [line 15]\n DECLARE_LOCALS(&objects); [line 15]\n DECLARE_LOCALS(&stop); [line 15]\n DECLARE_LOCALS(&idx); [line 15]\n DECLARE_LOCALS(&object); [line 15]\n n$18=*&a:class NSArray * [line 15]\n *&objects:class NSArray *=n$18 [line 15]\n REMOVE_TEMPS(n$18); [line 15]\n NULLIFY(&a,false); [line 15]\n " shape="box"] 25 -> 18 ; -24 [label="24: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 22]\n n$19=*&stop:BOOL * [line 22]\n *n$19:_Bool =1 [line 22]\n REMOVE_TEMPS(n$19); [line 22]\n NULLIFY(&stop,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] +24 [label="24: BinaryOperatorStmt: Assign \n NULLIFY(&ShouldStop,false); [line 22]\n n$16=*&stop:_Bool * [line 22]\n *n$16:_Bool =1 [line 22]\n REMOVE_TEMPS(n$16); [line 22]\n NULLIFY(&stop,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] 24 -> 21 ; -23 [label="23: Prune (false branch) \n n$18=*&ShouldStop:int [line 20]\n PRUNE((n$18 == 0), false); [line 20]\n REMOVE_TEMPS(n$18); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="invhouse"] +23 [label="23: Prune (false branch) \n n$15=*&ShouldStop:int [line 20]\n PRUNE((n$15 == 0), false); [line 20]\n REMOVE_TEMPS(n$15); [line 20]\n APPLY_ABSTRACTION; [line 20]\n " shape="invhouse"] 23 -> 21 ; -22 [label="22: Prune (true branch) \n n$18=*&ShouldStop:int [line 20]\n PRUNE((n$18 != 0), true); [line 20]\n REMOVE_TEMPS(n$18); [line 20]\n " shape="invhouse"] +22 [label="22: Prune (true branch) \n n$15=*&ShouldStop:int [line 20]\n PRUNE((n$15 != 0), true); [line 20]\n REMOVE_TEMPS(n$15); [line 20]\n " shape="invhouse"] 22 -> 24 ; @@ -131,40 +131,40 @@ digraph iCFG { 20 [label="20: Exit __objc_anonymous_block_MyBlock_array______1 \n " color=yellow style=filled] -19 [label="19: Start __objc_anonymous_block_MyBlock_array______1\nFormals: object:struct objc_object * idx:unsigned long stop:BOOL *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 15]\n NULLIFY(&idx,false); [line 15]\n NULLIFY(&object,false); [line 15]\n " color=yellow style=filled] +19 [label="19: Start __objc_anonymous_block_MyBlock_array______1\nFormals: object:struct objc_object * idx:unsigned long stop:_Bool *\nLocals: ShouldStop:int \n DECLARE_LOCALS(&return,&ShouldStop); [line 15]\n NULLIFY(&idx,false); [line 15]\n NULLIFY(&object,false); [line 15]\n " color=yellow style=filled] 19 -> 22 ; 19 -> 23 ; -18 [label="18: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array______1); [line 15]\n n$20=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array______1 ):unsigned long ) [line 15]\n *&__objc_anonymous_block_MyBlock_array______1:class __objc_anonymous_block_MyBlock_array______1 =n$20 [line 15]\n *&infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array______1) [line 15]\n REMOVE_TEMPS(n$20); [line 15]\n " shape="box"] +18 [label="18: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_MyBlock_array______1); [line 15]\n n$17=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_MyBlock_array______1 ):unsigned long ) [line 15]\n *&__objc_anonymous_block_MyBlock_array______1:class __objc_anonymous_block_MyBlock_array______1 =n$17 [line 15]\n *&infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*)=(_fun___objc_anonymous_block_MyBlock_array______1) [line 15]\n REMOVE_TEMPS(n$17); [line 15]\n " shape="box"] 18 -> 17 ; -17 [label="17: DeclStmt \n n$17=_fun_malloc_no_fail(sizeof(signed char ):signed char ) [line 15]\n *&stop:BOOL *=n$17 [line 15]\n REMOVE_TEMPS(n$17); [line 15]\n " shape="box"] +17 [label="17: DeclStmt \n _fun_malloc_no_fail(sizeof(signed char ):signed char ) [line 15]\n *&stop:_Bool *=-1 [line 15]\n " shape="box"] 17 -> 16 ; -16 [label="16: BinaryOperatorStmt: Assign \n n$16=*&stop:BOOL * [line 15]\n *n$16:void =0 [line 15]\n REMOVE_TEMPS(n$16); [line 15]\n " shape="box"] +16 [label="16: BinaryOperatorStmt: Assign \n n$14=*&stop:_Bool * [line 15]\n *n$14:void =0 [line 15]\n REMOVE_TEMPS(n$14); [line 15]\n " shape="box"] 16 -> 5 ; -15 [label="15: DeclStmt \n n$14=*&objects:class NSArray * [line 15]\n n$15=*&idx:unsigned long [line 15]\n n$13=_fun_NSArray_objectAtIndexedSubscript:(n$14:class NSArray *,n$15:unsigned long ) virtual [line 15]\n *&object:struct objc_object *=n$13 [line 15]\n REMOVE_TEMPS(n$13,n$14,n$15); [line 15]\n " shape="box"] +15 [label="15: DeclStmt \n n$12=*&objects:class NSArray * [line 15]\n n$13=*&idx:unsigned long [line 15]\n n$11=_fun_NSArray_objectAtIndexedSubscript:(n$12:class NSArray *,n$13:unsigned long ) virtual [line 15]\n *&object:struct objc_object *=n$11 [line 15]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 15]\n " shape="box"] 15 -> 14 ; -14 [label="14: Call n$8 \n n$8=*&infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*) [line 15]\n n$9=*&object:struct objc_object * [line 15]\n n$10=*&idx:unsigned long [line 15]\n n$11=*&stop:BOOL * [line 15]\n n$12=n$8(n$9:struct objc_object *,n$10:unsigned long ,n$11:BOOL *) [line 15]\n REMOVE_TEMPS(n$8,n$9,n$10,n$11,n$12); [line 15]\n " shape="box"] +14 [label="14: Call n$7 \n n$7=*&infer___objc_anonymous_block_MyBlock_array______1:_fn_ (*) [line 15]\n n$8=*&object:struct objc_object * [line 15]\n n$9=*&idx:unsigned long [line 15]\n n$10=*&stop:_Bool * [line 15]\n n$7(n$8:struct objc_object *,n$9:unsigned long ,n$10:_Bool *) [line 15]\n REMOVE_TEMPS(n$7,n$8,n$9,n$10); [line 15]\n " shape="box"] 14 -> 11 ; -13 [label="13: Prune (false branch) \n n$7=*n$6:signed char [line 15]\n PRUNE((n$7 == 0), false); [line 15]\n REMOVE_TEMPS(n$6,n$7); [line 15]\n " shape="invhouse"] +13 [label="13: Prune (false branch) \n n$6=*n$5:signed char [line 15]\n PRUNE((n$6 == 0), false); [line 15]\n REMOVE_TEMPS(n$5,n$6); [line 15]\n " shape="invhouse"] 13 -> 10 ; -12 [label="12: Prune (true branch) \n n$7=*n$6:signed char [line 15]\n PRUNE((n$7 != 0), true); [line 15]\n REMOVE_TEMPS(n$6,n$7); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] +12 [label="12: Prune (true branch) \n n$6=*n$5:signed char [line 15]\n PRUNE((n$6 != 0), true); [line 15]\n REMOVE_TEMPS(n$5,n$6); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] 12 -> 3 ; -11 [label="11: UnaryOperator \n n$6=*&stop:BOOL * [line 15]\n " shape="box"] +11 [label="11: UnaryOperator \n n$5=*&stop:_Bool * [line 15]\n " shape="box"] 11 -> 12 ; @@ -173,20 +173,20 @@ digraph iCFG { 10 -> 6 ; -9 [label="9: Prune (false branch) \n PRUNE(((n$3 < n$4) == 0), false); [line 15]\n REMOVE_TEMPS(n$3,n$4,n$5); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] +9 [label="9: Prune (false branch) \n PRUNE(((n$2 < n$3) == 0), false); [line 15]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="invhouse"] 9 -> 3 ; -8 [label="8: Prune (true branch) \n PRUNE(((n$3 < n$4) != 0), true); [line 15]\n REMOVE_TEMPS(n$3,n$4,n$5); [line 15]\n " shape="invhouse"] +8 [label="8: Prune (true branch) \n PRUNE(((n$2 < n$3) != 0), true); [line 15]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 15]\n " shape="invhouse"] 8 -> 15 ; -7 [label="7: BinaryOperatorStmt: LT \n n$3=*&idx:unsigned long [line 15]\n n$5=*&objects:class NSArray * [line 15]\n n$4=_fun_NSArray_count(n$5:class NSArray *) virtual [line 15]\n " shape="box"] +7 [label="7: BinaryOperatorStmt: LT \n n$2=*&idx:unsigned long [line 15]\n n$4=*&objects:class NSArray * [line 15]\n n$3=_fun_NSArray_count(n$4:class NSArray *) virtual [line 15]\n " shape="box"] 7 -> 8 ; 7 -> 9 ; -6 [label="6: UnaryOperator \n n$2=*&idx:unsigned long [line 15]\n *&idx:unsigned long =(n$2 + 1) [line 15]\n REMOVE_TEMPS(n$2); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] +6 [label="6: UnaryOperator \n n$1=*&idx:unsigned long [line 15]\n *&idx:unsigned long =(n$1 + 1) [line 15]\n REMOVE_TEMPS(n$1); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] 6 -> 4 ; @@ -198,7 +198,7 @@ digraph iCFG { 4 -> 7 ; -3 [label="3: Call _fun_free \n n$0=*&stop:BOOL * [line 15]\n n$1=_fun_free(n$0:void *) [line 15]\n NULLIFY(&object,true); [line 15]\n NULLIFY(&idx,true); [line 15]\n NULLIFY(&stop,true); [line 15]\n NULLIFY(&objects,true); [line 15]\n REMOVE_TEMPS(n$0,n$1); [line 15]\n NULLIFY(&__objc_anonymous_block_MyBlock_array______1,true); [line 15]\n NULLIFY(&infer___objc_anonymous_block_MyBlock_array______1,true); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] +3 [label="3: Call _fun_free \n n$0=*&stop:_Bool * [line 15]\n _fun_free(n$0:void ) [line 15]\n NULLIFY(&object,true); [line 15]\n NULLIFY(&idx,true); [line 15]\n NULLIFY(&stop,true); [line 15]\n NULLIFY(&objects,true); [line 15]\n REMOVE_TEMPS(n$0); [line 15]\n NULLIFY(&__objc_anonymous_block_MyBlock_array______1,true); [line 15]\n NULLIFY(&infer___objc_anonymous_block_MyBlock_array______1,true); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] 3 -> 2 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot b/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot index 0783b6dd7..03650a6af 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/block_release.dot @@ -7,7 +7,7 @@ digraph iCFG { 18 -> 17 ; -17 [label="17: DeclStmt \n n$12=_fun_CGBitmapContextCreate(0:void *,0:unsigned long ,0:unsigned long ,8:unsigned long ,0:unsigned long ,0:struct CGColorSpace *,0:enum CGBitmapInfo ) [line 27]\n *&context:struct CGContext *=n$12 [line 27]\n REMOVE_TEMPS(n$12); [line 27]\n " shape="box"] +17 [label="17: DeclStmt \n n$12=_fun_CGBitmapContextCreate(0:void *,0:unsigned long ,0:unsigned long ,8:unsigned long ,0:unsigned long ,0:struct CGColorSpace *,0:CGBitmapInfo ) [line 27]\n *&context:struct CGContext *=n$12 [line 27]\n REMOVE_TEMPS(n$12); [line 27]\n " shape="box"] 17 -> 16 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot index d81e73299..dd60e561d 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch.dot @@ -29,7 +29,7 @@ digraph iCFG { 23 -> 30 ; -19 [label="19: Return Stmt \n n$13=*&self:class A * [line 14]\n n$14=*n$13._x:int [line 14]\n *&return:int =n$14 [line 14]\n REMOVE_TEMPS(n$13,n$14); [line 14]\n NULLIFY(&self,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] +19 [label="19: Return Stmt \n n$12=*&self:class A * [line 14]\n n$13=*n$12._x:int [line 14]\n *&return:int =n$13 [line 14]\n REMOVE_TEMPS(n$12,n$13); [line 14]\n NULLIFY(&self,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] 19 -> 18 ; @@ -40,7 +40,7 @@ digraph iCFG { 17 -> 19 ; -16 [label="16: BinaryOperatorStmt: Assign \n n$11=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 41]\n n$9=_fun_A_init(n$11:class A *) virtual [line 41]\n *&#GB$A_trans_SI_sharedInstance:struct objc_object *=n$9 [line 41]\n REMOVE_TEMPS(n$9,n$11); [line 41]\n APPLY_ABSTRACTION; [line 41]\n " shape="box"] +16 [label="16: BinaryOperatorStmt: Assign \n n$10=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 41]\n n$8=_fun_A_init(n$10:class A *) virtual [line 41]\n *&#GB$A_trans_SI_sharedInstance:struct objc_object *=n$8 [line 41]\n REMOVE_TEMPS(n$8,n$10); [line 41]\n APPLY_ABSTRACTION; [line 41]\n " shape="box"] 16 -> 15 ; @@ -51,15 +51,15 @@ digraph iCFG { 14 -> 16 ; -13 [label="13: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans_SI______2); [line 40]\n n$12=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans_SI______2 ):unsigned long ) [line 40]\n *&__objc_anonymous_block_A_trans_SI______2:class __objc_anonymous_block_A_trans_SI______2 =n$12 [line 40]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans_SI______2) [line 40]\n REMOVE_TEMPS(n$12); [line 40]\n " shape="box"] +13 [label="13: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans_SI______2); [line 40]\n n$11=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans_SI______2 ):unsigned long ) [line 40]\n *&__objc_anonymous_block_A_trans_SI______2:class __objc_anonymous_block_A_trans_SI______2 =n$11 [line 40]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans_SI______2) [line 40]\n REMOVE_TEMPS(n$11); [line 40]\n " shape="box"] 13 -> 12 ; -12 [label="12: Call n$8 \n n$8=*&dummy_block:_fn_ (*) [line 43]\n n$8() [line 43]\n REMOVE_TEMPS(n$8); [line 43]\n NULLIFY(&dummy_block,false); [line 43]\n " shape="box"] +12 [label="12: Call n$7 \n n$7=*&dummy_block:_fn_ (*) [line 43]\n n$7() [line 43]\n REMOVE_TEMPS(n$7); [line 43]\n NULLIFY(&dummy_block,false); [line 43]\n " shape="box"] 12 -> 11 ; -11 [label="11: Return Stmt \n n$7=*&#GB$A_trans_SI_sharedInstance:struct objc_object * [line 44]\n *&return:struct objc_object *=n$7 [line 44]\n REMOVE_TEMPS(n$7); [line 44]\n NULLIFY(&__objc_anonymous_block_A_trans_SI______2,true); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"] +11 [label="11: Return Stmt \n n$6=*&#GB$A_trans_SI_sharedInstance:struct objc_object * [line 44]\n *&return:struct objc_object *=n$6 [line 44]\n REMOVE_TEMPS(n$6); [line 44]\n NULLIFY(&__objc_anonymous_block_A_trans_SI______2,true); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"] 11 -> 10 ; @@ -70,7 +70,7 @@ digraph iCFG { 9 -> 13 ; -8 [label="8: BinaryOperatorStmt: Assign \n n$5=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 29]\n n$3=_fun_A_init(n$5:class A *) virtual [line 29]\n *&#GB$A_sharedInstance_sharedInstance:struct objc_object *=n$3 [line 29]\n REMOVE_TEMPS(n$3,n$5); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] +8 [label="8: BinaryOperatorStmt: Assign \n n$4=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 29]\n n$2=_fun_A_init(n$4:class A *) virtual [line 29]\n *&#GB$A_sharedInstance_sharedInstance:struct objc_object *=n$2 [line 29]\n REMOVE_TEMPS(n$2,n$4); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] 8 -> 7 ; @@ -81,11 +81,11 @@ digraph iCFG { 6 -> 8 ; -5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_sharedInstance______1); [line 30]\n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 28]\n n$6=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 28]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$6 [line 28]\n *&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*)=(_fun___objc_anonymous_block_A_sharedInstance______1) [line 30]\n REMOVE_TEMPS(n$6); [line 30]\n " shape="box"] +5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_sharedInstance______1); [line 30]\n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 28]\n n$5=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 28]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$5 [line 28]\n *&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*)=(_fun___objc_anonymous_block_A_sharedInstance______1) [line 30]\n REMOVE_TEMPS(n$5); [line 30]\n " shape="box"] 5 -> 4 ; -4 [label="4: Call n$1 \n n$1=*&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*) [line 30]\n n$2=n$1() [line 30]\n REMOVE_TEMPS(n$1,n$2); [line 30]\n NULLIFY(&infer___objc_anonymous_block_A_sharedInstance______1,true); [line 30]\n " shape="box"] +4 [label="4: Call n$1 \n n$1=*&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*) [line 30]\n n$1() [line 30]\n REMOVE_TEMPS(n$1); [line 30]\n NULLIFY(&infer___objc_anonymous_block_A_sharedInstance______1,true); [line 30]\n " shape="box"] 4 -> 3 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot index 7a5934295..f767b0252 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/dispatch_examples.dot @@ -3,11 +3,11 @@ digraph iCFG { 60 -> 55 ; -59 [label="59: BinaryOperatorStmt: Assign \n n$52=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 71]\n n$50=_fun_A_init(n$52:class A *) virtual [line 71]\n *&#GB$A_dispatch_barrier_example_a:class A *=n$50 [line 71]\n REMOVE_TEMPS(n$50,n$52); [line 71]\n " shape="box"] +59 [label="59: BinaryOperatorStmt: Assign \n n$46=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 71]\n n$44=_fun_A_init(n$46:class A *) virtual [line 71]\n *&#GB$A_dispatch_barrier_example_a:class A *=n$44 [line 71]\n REMOVE_TEMPS(n$44,n$46); [line 71]\n " shape="box"] 59 -> 58 ; -58 [label="58: BinaryOperatorStmt: Assign \n n$49=*&#GB$A_dispatch_barrier_example_a:class A * [line 72]\n *n$49.x:int =10 [line 72]\n REMOVE_TEMPS(n$49); [line 72]\n APPLY_ABSTRACTION; [line 72]\n " shape="box"] +58 [label="58: BinaryOperatorStmt: Assign \n n$43=*&#GB$A_dispatch_barrier_example_a:class A * [line 72]\n *n$43.x:int =10 [line 72]\n REMOVE_TEMPS(n$43); [line 72]\n APPLY_ABSTRACTION; [line 72]\n " shape="box"] 58 -> 57 ; @@ -18,15 +18,15 @@ digraph iCFG { 56 -> 59 ; -55 [label="55: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n n$53=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_barrier_example______6 ):unsigned long ) [line 70]\n *&__objc_anonymous_block_A_dispatch_barrier_example______6:class __objc_anonymous_block_A_dispatch_barrier_example______6 =n$53 [line 70]\n *&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_barrier_example______6) [line 70]\n REMOVE_TEMPS(n$53); [line 70]\n " shape="box"] +55 [label="55: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n n$47=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_barrier_example______6 ):unsigned long ) [line 70]\n *&__objc_anonymous_block_A_dispatch_barrier_example______6:class __objc_anonymous_block_A_dispatch_barrier_example______6 =n$47 [line 70]\n *&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_barrier_example______6) [line 70]\n REMOVE_TEMPS(n$47); [line 70]\n " shape="box"] 55 -> 54 ; -54 [label="54: Call n$47 \n n$47=*&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*) [line 70]\n n$48=n$47() [line 70]\n REMOVE_TEMPS(n$47,n$48); [line 70]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 70]\n " shape="box"] +54 [label="54: Call n$42 \n n$42=*&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*) [line 70]\n n$42() [line 70]\n REMOVE_TEMPS(n$42); [line 70]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 70]\n " shape="box"] 54 -> 53 ; -53 [label="53: Return Stmt \n n$45=*&#GB$A_dispatch_barrier_example_a:class A * [line 74]\n n$46=*n$45.x:int [line 74]\n *&return:int =n$46 [line 74]\n REMOVE_TEMPS(n$45,n$46); [line 74]\n NULLIFY(&__objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 74]\n APPLY_ABSTRACTION; [line 74]\n " shape="box"] +53 [label="53: Return Stmt \n n$40=*&#GB$A_dispatch_barrier_example_a:class A * [line 74]\n n$41=*n$40.x:int [line 74]\n *&return:int =n$41 [line 74]\n REMOVE_TEMPS(n$40,n$41); [line 74]\n NULLIFY(&__objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 74]\n APPLY_ABSTRACTION; [line 74]\n " shape="box"] 53 -> 52 ; @@ -41,11 +41,11 @@ digraph iCFG { 50 -> 45 ; -49 [label="49: BinaryOperatorStmt: Assign \n n$43=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 62]\n n$41=_fun_A_init(n$43:class A *) virtual [line 62]\n *&#GB$A_dispatch_group_notify_example_a:class A *=n$41 [line 62]\n REMOVE_TEMPS(n$41,n$43); [line 62]\n " shape="box"] +49 [label="49: BinaryOperatorStmt: Assign \n n$38=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 62]\n n$36=_fun_A_init(n$38:class A *) virtual [line 62]\n *&#GB$A_dispatch_group_notify_example_a:class A *=n$36 [line 62]\n REMOVE_TEMPS(n$36,n$38); [line 62]\n " shape="box"] 49 -> 48 ; -48 [label="48: BinaryOperatorStmt: Assign \n n$40=*&#GB$A_dispatch_group_notify_example_a:class A * [line 63]\n *n$40.x:int =10 [line 63]\n REMOVE_TEMPS(n$40); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"] +48 [label="48: BinaryOperatorStmt: Assign \n n$35=*&#GB$A_dispatch_group_notify_example_a:class A * [line 63]\n *n$35.x:int =10 [line 63]\n REMOVE_TEMPS(n$35); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"] 48 -> 47 ; @@ -56,15 +56,15 @@ digraph iCFG { 46 -> 49 ; -45 [label="45: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n n$44=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_notify_example______5 ):unsigned long ) [line 61]\n *&__objc_anonymous_block_A_dispatch_group_notify_example______5:class __objc_anonymous_block_A_dispatch_group_notify_example______5 =n$44 [line 61]\n *&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_notify_example______5) [line 61]\n REMOVE_TEMPS(n$44); [line 61]\n " shape="box"] +45 [label="45: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n n$39=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_notify_example______5 ):unsigned long ) [line 61]\n *&__objc_anonymous_block_A_dispatch_group_notify_example______5:class __objc_anonymous_block_A_dispatch_group_notify_example______5 =n$39 [line 61]\n *&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_notify_example______5) [line 61]\n REMOVE_TEMPS(n$39); [line 61]\n " shape="box"] 45 -> 44 ; -44 [label="44: Call n$38 \n n$38=*&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*) [line 61]\n n$39=n$38() [line 61]\n REMOVE_TEMPS(n$38,n$39); [line 61]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 61]\n " shape="box"] +44 [label="44: Call n$34 \n n$34=*&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*) [line 61]\n n$34() [line 61]\n REMOVE_TEMPS(n$34); [line 61]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 61]\n " shape="box"] 44 -> 43 ; -43 [label="43: Return Stmt \n n$36=*&#GB$A_dispatch_group_notify_example_a:class A * [line 65]\n n$37=*n$36.x:int [line 65]\n *&return:int =n$37 [line 65]\n REMOVE_TEMPS(n$36,n$37); [line 65]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] +43 [label="43: Return Stmt \n n$32=*&#GB$A_dispatch_group_notify_example_a:class A * [line 65]\n n$33=*n$32.x:int [line 65]\n *&return:int =n$33 [line 65]\n REMOVE_TEMPS(n$32,n$33); [line 65]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] 43 -> 42 ; @@ -79,11 +79,11 @@ digraph iCFG { 40 -> 35 ; -39 [label="39: BinaryOperatorStmt: Assign \n n$34=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 53]\n n$32=_fun_A_init(n$34:class A *) virtual [line 53]\n *&#GB$A_dispatch_group_example_a:class A *=n$32 [line 53]\n REMOVE_TEMPS(n$32,n$34); [line 53]\n " shape="box"] +39 [label="39: BinaryOperatorStmt: Assign \n n$30=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 53]\n n$28=_fun_A_init(n$30:class A *) virtual [line 53]\n *&#GB$A_dispatch_group_example_a:class A *=n$28 [line 53]\n REMOVE_TEMPS(n$28,n$30); [line 53]\n " shape="box"] 39 -> 38 ; -38 [label="38: BinaryOperatorStmt: Assign \n n$31=*&#GB$A_dispatch_group_example_a:class A * [line 54]\n *n$31.x:int =10 [line 54]\n REMOVE_TEMPS(n$31); [line 54]\n APPLY_ABSTRACTION; [line 54]\n " shape="box"] +38 [label="38: BinaryOperatorStmt: Assign \n n$27=*&#GB$A_dispatch_group_example_a:class A * [line 54]\n *n$27.x:int =10 [line 54]\n REMOVE_TEMPS(n$27); [line 54]\n APPLY_ABSTRACTION; [line 54]\n " shape="box"] 38 -> 37 ; @@ -94,15 +94,15 @@ digraph iCFG { 36 -> 39 ; -35 [label="35: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n n$35=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_example______4 ):unsigned long ) [line 52]\n *&__objc_anonymous_block_A_dispatch_group_example______4:class __objc_anonymous_block_A_dispatch_group_example______4 =n$35 [line 52]\n *&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_example______4) [line 52]\n REMOVE_TEMPS(n$35); [line 52]\n " shape="box"] +35 [label="35: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n n$31=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_example______4 ):unsigned long ) [line 52]\n *&__objc_anonymous_block_A_dispatch_group_example______4:class __objc_anonymous_block_A_dispatch_group_example______4 =n$31 [line 52]\n *&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_example______4) [line 52]\n REMOVE_TEMPS(n$31); [line 52]\n " shape="box"] 35 -> 34 ; -34 [label="34: Call n$29 \n n$29=*&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*) [line 52]\n n$30=n$29() [line 52]\n REMOVE_TEMPS(n$29,n$30); [line 52]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_example______4,true); [line 52]\n " shape="box"] +34 [label="34: Call n$26 \n n$26=*&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*) [line 52]\n n$26() [line 52]\n REMOVE_TEMPS(n$26); [line 52]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_example______4,true); [line 52]\n " shape="box"] 34 -> 33 ; -33 [label="33: Return Stmt \n n$27=*&#GB$A_dispatch_group_example_a:class A * [line 56]\n n$28=*n$27.x:int [line 56]\n *&return:int =n$28 [line 56]\n REMOVE_TEMPS(n$27,n$28); [line 56]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_example______4,true); [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"] +33 [label="33: Return Stmt \n n$24=*&#GB$A_dispatch_group_example_a:class A * [line 56]\n n$25=*n$24.x:int [line 56]\n *&return:int =n$25 [line 56]\n REMOVE_TEMPS(n$24,n$25); [line 56]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_example______4,true); [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"] 33 -> 32 ; @@ -117,11 +117,11 @@ digraph iCFG { 30 -> 25 ; -29 [label="29: BinaryOperatorStmt: Assign \n n$25=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 44]\n n$23=_fun_A_init(n$25:class A *) virtual [line 44]\n *&#GB$A_dispatch_after_example_a:class A *=n$23 [line 44]\n REMOVE_TEMPS(n$23,n$25); [line 44]\n " shape="box"] +29 [label="29: BinaryOperatorStmt: Assign \n n$22=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 44]\n n$20=_fun_A_init(n$22:class A *) virtual [line 44]\n *&#GB$A_dispatch_after_example_a:class A *=n$20 [line 44]\n REMOVE_TEMPS(n$20,n$22); [line 44]\n " shape="box"] 29 -> 28 ; -28 [label="28: BinaryOperatorStmt: Assign \n n$22=*&#GB$A_dispatch_after_example_a:class A * [line 45]\n *n$22.x:int =10 [line 45]\n REMOVE_TEMPS(n$22); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] +28 [label="28: BinaryOperatorStmt: Assign \n n$19=*&#GB$A_dispatch_after_example_a:class A * [line 45]\n *n$19.x:int =10 [line 45]\n REMOVE_TEMPS(n$19); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] 28 -> 27 ; @@ -132,15 +132,15 @@ digraph iCFG { 26 -> 29 ; -25 [label="25: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_after_example______3); [line 42]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_after_example______3); [line 43]\n n$26=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_after_example______3 ):unsigned long ) [line 43]\n *&__objc_anonymous_block_A_dispatch_after_example______3:class __objc_anonymous_block_A_dispatch_after_example______3 =n$26 [line 43]\n *&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_after_example______3) [line 42]\n REMOVE_TEMPS(n$26); [line 42]\n " shape="box"] +25 [label="25: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_after_example______3); [line 42]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_after_example______3); [line 43]\n n$23=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_after_example______3 ):unsigned long ) [line 43]\n *&__objc_anonymous_block_A_dispatch_after_example______3:class __objc_anonymous_block_A_dispatch_after_example______3 =n$23 [line 43]\n *&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_after_example______3) [line 42]\n REMOVE_TEMPS(n$23); [line 42]\n " shape="box"] 25 -> 24 ; -24 [label="24: Call n$20 \n n$20=*&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*) [line 42]\n n$21=n$20() [line 42]\n REMOVE_TEMPS(n$20,n$21); [line 42]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_after_example______3,true); [line 42]\n " shape="box"] +24 [label="24: Call n$18 \n n$18=*&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*) [line 42]\n n$18() [line 42]\n REMOVE_TEMPS(n$18); [line 42]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_after_example______3,true); [line 42]\n " shape="box"] 24 -> 23 ; -23 [label="23: Return Stmt \n n$18=*&#GB$A_dispatch_after_example_a:class A * [line 47]\n n$19=*n$18.x:int [line 47]\n *&return:int =n$19 [line 47]\n REMOVE_TEMPS(n$18,n$19); [line 47]\n NULLIFY(&__objc_anonymous_block_A_dispatch_after_example______3,true); [line 47]\n APPLY_ABSTRACTION; [line 47]\n " shape="box"] +23 [label="23: Return Stmt \n n$16=*&#GB$A_dispatch_after_example_a:class A * [line 47]\n n$17=*n$16.x:int [line 47]\n *&return:int =n$17 [line 47]\n REMOVE_TEMPS(n$16,n$17); [line 47]\n NULLIFY(&__objc_anonymous_block_A_dispatch_after_example______3,true); [line 47]\n APPLY_ABSTRACTION; [line 47]\n " shape="box"] 23 -> 22 ; @@ -155,11 +155,11 @@ digraph iCFG { 20 -> 15 ; -19 [label="19: BinaryOperatorStmt: Assign \n n$16=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 34]\n n$14=_fun_A_init(n$16:class A *) virtual [line 34]\n *&#GB$A_dispatch_async_example_a:class A *=n$14 [line 34]\n REMOVE_TEMPS(n$14,n$16); [line 34]\n " shape="box"] +19 [label="19: BinaryOperatorStmt: Assign \n n$14=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 34]\n n$12=_fun_A_init(n$14:class A *) virtual [line 34]\n *&#GB$A_dispatch_async_example_a:class A *=n$12 [line 34]\n REMOVE_TEMPS(n$12,n$14); [line 34]\n " shape="box"] 19 -> 18 ; -18 [label="18: BinaryOperatorStmt: Assign \n n$13=*&#GB$A_dispatch_async_example_a:class A * [line 35]\n *n$13.x:int =10 [line 35]\n REMOVE_TEMPS(n$13); [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"] +18 [label="18: BinaryOperatorStmt: Assign \n n$11=*&#GB$A_dispatch_async_example_a:class A * [line 35]\n *n$11.x:int =10 [line 35]\n REMOVE_TEMPS(n$11); [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"] 18 -> 17 ; @@ -170,15 +170,15 @@ digraph iCFG { 16 -> 19 ; -15 [label="15: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n n$17=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_async_example______2 ):unsigned long ) [line 33]\n *&__objc_anonymous_block_A_dispatch_async_example______2:class __objc_anonymous_block_A_dispatch_async_example______2 =n$17 [line 33]\n *&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_async_example______2) [line 33]\n REMOVE_TEMPS(n$17); [line 33]\n " shape="box"] +15 [label="15: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n n$15=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_async_example______2 ):unsigned long ) [line 33]\n *&__objc_anonymous_block_A_dispatch_async_example______2:class __objc_anonymous_block_A_dispatch_async_example______2 =n$15 [line 33]\n *&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_async_example______2) [line 33]\n REMOVE_TEMPS(n$15); [line 33]\n " shape="box"] 15 -> 14 ; -14 [label="14: Call n$11 \n n$11=*&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*) [line 33]\n n$12=n$11() [line 33]\n REMOVE_TEMPS(n$11,n$12); [line 33]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_async_example______2,true); [line 33]\n " shape="box"] +14 [label="14: Call n$10 \n n$10=*&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*) [line 33]\n n$10() [line 33]\n REMOVE_TEMPS(n$10); [line 33]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_async_example______2,true); [line 33]\n " shape="box"] 14 -> 13 ; -13 [label="13: Return Stmt \n n$9=*&#GB$A_dispatch_async_example_a:class A * [line 37]\n n$10=*n$9.x:int [line 37]\n *&return:int =n$10 [line 37]\n REMOVE_TEMPS(n$9,n$10); [line 37]\n NULLIFY(&__objc_anonymous_block_A_dispatch_async_example______2,true); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] +13 [label="13: Return Stmt \n n$8=*&#GB$A_dispatch_async_example_a:class A * [line 37]\n n$9=*n$8.x:int [line 37]\n *&return:int =n$9 [line 37]\n REMOVE_TEMPS(n$8,n$9); [line 37]\n NULLIFY(&__objc_anonymous_block_A_dispatch_async_example______2,true); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] 13 -> 12 ; @@ -193,11 +193,11 @@ digraph iCFG { 10 -> 5 ; -9 [label="9: BinaryOperatorStmt: Assign \n n$7=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 25]\n n$5=_fun_A_init(n$7:class A *) virtual [line 25]\n *&#GB$A_dispatch_once_example_a:class A *=n$5 [line 25]\n REMOVE_TEMPS(n$5,n$7); [line 25]\n " shape="box"] +9 [label="9: BinaryOperatorStmt: Assign \n n$6=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 25]\n n$4=_fun_A_init(n$6:class A *) virtual [line 25]\n *&#GB$A_dispatch_once_example_a:class A *=n$4 [line 25]\n REMOVE_TEMPS(n$4,n$6); [line 25]\n " shape="box"] 9 -> 8 ; -8 [label="8: BinaryOperatorStmt: Assign \n n$4=*&#GB$A_dispatch_once_example_a:class A * [line 26]\n *n$4.x:int =10 [line 26]\n REMOVE_TEMPS(n$4); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] +8 [label="8: BinaryOperatorStmt: Assign \n n$3=*&#GB$A_dispatch_once_example_a:class A * [line 26]\n *n$3.x:int =10 [line 26]\n REMOVE_TEMPS(n$3); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] 8 -> 7 ; @@ -208,11 +208,11 @@ digraph iCFG { 6 -> 9 ; -5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_once_example______1); [line 23]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_once_example______1); [line 24]\n n$8=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_once_example______1 ):unsigned long ) [line 24]\n *&__objc_anonymous_block_A_dispatch_once_example______1:class __objc_anonymous_block_A_dispatch_once_example______1 =n$8 [line 24]\n *&infer___objc_anonymous_block_A_dispatch_once_example______1:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_once_example______1) [line 23]\n REMOVE_TEMPS(n$8); [line 23]\n " shape="box"] +5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_once_example______1); [line 23]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_once_example______1); [line 24]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_once_example______1 ):unsigned long ) [line 24]\n *&__objc_anonymous_block_A_dispatch_once_example______1:class __objc_anonymous_block_A_dispatch_once_example______1 =n$7 [line 24]\n *&infer___objc_anonymous_block_A_dispatch_once_example______1:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_once_example______1) [line 23]\n REMOVE_TEMPS(n$7); [line 23]\n " shape="box"] 5 -> 4 ; -4 [label="4: Call n$2 \n n$2=*&infer___objc_anonymous_block_A_dispatch_once_example______1:_fn_ (*) [line 23]\n n$3=n$2() [line 23]\n REMOVE_TEMPS(n$2,n$3); [line 23]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_once_example______1,true); [line 23]\n " shape="box"] +4 [label="4: Call n$2 \n n$2=*&infer___objc_anonymous_block_A_dispatch_once_example______1:_fn_ (*) [line 23]\n n$2() [line 23]\n REMOVE_TEMPS(n$2); [line 23]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_once_example______1,true); [line 23]\n " shape="box"] 4 -> 3 ; diff --git a/infer/tests/codetoanalyze/objc/frontend/vardecl/initlist.dot b/infer/tests/codetoanalyze/objc/frontend/vardecl/initlist.dot index ca12d728a..bd61e5b86 100644 --- a/infer/tests/codetoanalyze/objc/frontend/vardecl/initlist.dot +++ b/infer/tests/codetoanalyze/objc/frontend/vardecl/initlist.dot @@ -7,14 +7,14 @@ digraph iCFG { 7 -> 6 ; -6 [label="6: InitListExp \n n$1=*&c1:class C * [line 24]\n n$0=_fun_C_init(n$1:class C *) virtual [line 24]\n n$2=*&c1:class C * [line 24]\n n$3=*&c2:class C * [line 24]\n *&a[0]:C *=n$0 [line 24]\n _fun___objc_retain(n$2:C *) [line 24]\n *&a[1]:C *=n$2 [line 24]\n _fun___objc_retain(n$3:C *) [line 24]\n *&a[2]:C *=n$3 [line 24]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 24]\n NULLIFY(&c1,false); [line 24]\n NULLIFY(&c2,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] +6 [label="6: InitListExp \n n$1=*&c1:class C * [line 24]\n n$0=_fun_C_init(n$1:class C *) virtual [line 24]\n n$2=*&c1:class C * [line 24]\n n$3=*&c2:class C * [line 24]\n *&a[0]:class C *=n$0 [line 24]\n _fun___objc_retain(n$2:class C *) [line 24]\n *&a[1]:class C *=n$2 [line 24]\n _fun___objc_retain(n$3:class C *) [line 24]\n *&a[2]:class C *=n$3 [line 24]\n REMOVE_TEMPS(n$0,n$1,n$2,n$3); [line 24]\n NULLIFY(&c1,false); [line 24]\n NULLIFY(&c2,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] 6 -> 5 ; 5 [label="5: Exit test \n " color=yellow style=filled] -4 [label="4: Start test\nFormals: \nLocals: c1:class C * c2:class C * a:C *[3] \n DECLARE_LOCALS(&return,&c1,&c2,&a); [line 21]\n NULLIFY(&a,false); [line 21]\n NULLIFY(&c1,false); [line 21]\n NULLIFY(&c2,false); [line 21]\n " color=yellow style=filled] +4 [label="4: Start test\nFormals: \nLocals: c1:class C * c2:class C * a:class C *[3] \n DECLARE_LOCALS(&return,&c1,&c2,&a); [line 21]\n NULLIFY(&a,false); [line 21]\n NULLIFY(&c1,false); [line 21]\n NULLIFY(&c2,false); [line 21]\n " color=yellow style=filled] 4 -> 8 ;