diff --git a/infer/src/clang/cAst_utils.ml b/infer/src/clang/cAst_utils.ml index bfd73ad36..9138f2708 100644 --- a/infer/src/clang/cAst_utils.ml +++ b/infer/src/clang/cAst_utils.ml @@ -470,3 +470,12 @@ let get_record_fields decl = -> List.filter ~f:(function FieldDecl _ -> true | _ -> false) decl_list | _ -> [] + +let get_cxx_base_classes decl = + let open Clang_ast_t in + match decl with + | CXXRecordDecl (_, _, _, _, _, _, _, cxx_record_info) + | ClassTemplateSpecializationDecl (_, _, _, _, _, _, _, cxx_record_info, _) + -> cxx_record_info.xrdi_bases + | _ + -> [] diff --git a/infer/src/clang/cAst_utils.mli b/infer/src/clang/cAst_utils.mli index 1b33f249e..b8cdce16f 100644 --- a/infer/src/clang/cAst_utils.mli +++ b/infer/src/clang/cAst_utils.mli @@ -144,3 +144,5 @@ val sil_annot_of_type : Clang_ast_t.qual_type -> Annot.Item.t val type_of_decl : Clang_ast_t.decl -> Clang_ast_t.type_ptr option val get_record_fields : Clang_ast_t.decl -> Clang_ast_t.decl list + +val get_cxx_base_classes : Clang_ast_t.decl -> Clang_ast_t.type_ptr list diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index ae4c46b26..420c2548d 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1309,6 +1309,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s let class_ptr = CContext.get_curr_class_decl_ptr context.CContext.curr_class in let decl = Option.value_exn (CAst_utils.get_decl class_ptr) in let fields = CAst_utils.get_record_fields decl in + let bases = CAst_utils.get_cxx_base_classes decl in (* compute `this` once that is used for all fields *) let class_qual_type = CAst_utils.qual_type_of_decl_ptr class_ptr in let _, sloc2 = stmt_info.Clang_ast_t.si_source_range in @@ -1322,6 +1323,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s extract_exp_from_list this_res_trans.exps "WARNING: There should be one expression for 'this' in constructor. @\n" in + let this_qual_type = match class_typ.desc with Typ.Tptr (t, _) -> t | _ -> class_typ in (* ReturnStmt claims a priority with the same `stmt_info`. New pointer is generated to avoid premature node creation *) let stmt_info' = @@ -1339,9 +1341,6 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s -> assert false in let field_name = CGeneral_utils.mk_class_field_name class_tname ni_name in - let this_qual_type = - match class_typ.desc with Typ.Tptr (t, _) -> t | _ -> class_typ - in let field_exp = Exp.Lfield (obj_sil, field_name, this_qual_type) in let field_typ = CType_decl.qual_type_to_sil_type context.tenv qual_type in let this_res_trans_destruct = @@ -1352,7 +1351,16 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s | _ -> assert false ) in - let all_res_trans = List.filter ~f:(fun res -> res <> empty_res_trans) all_res_trans in + let bases_res_trans = + List.rev_map bases ~f:(fun base -> + let this_res_trans_destruct = + {empty_res_trans with exps= [(obj_sil, this_qual_type)]} + in + cxx_destructor_call_trans trans_state_pri stmt_info_loc this_res_trans_destruct base ) + in + let all_res_trans = + List.filter ~f:(fun res -> res <> empty_res_trans) (all_res_trans @ bases_res_trans) + in let all_res_trans = if all_res_trans <> [] then {empty_res_trans with instrs= this_res_trans.instrs} :: all_res_trans diff --git a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main.cpp.dot b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main.cpp.dot index 67823c5f8..645d73779 100644 --- a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main.cpp.dot +++ b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main.cpp.dot @@ -210,14 +210,18 @@ digraph iCFG { "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" [label="1: Start std::shared_ptr_~shared_ptr\nFormals: this:int**\nLocals: \n DECLARE_LOCALS(&return); [line 182]\n " color=yellow style=filled] - "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" ; "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" [label="2: Exit std::shared_ptr_~shared_ptr \n " color=yellow style=filled] -"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Call _fun_std::shared_ptr_reset \n n$1=*&this:int** [line 182]\n _=*n$1:int* [line 182]\n _fun_std::shared_ptr_reset(n$1:int**,null:int*) [line 182]\n " shape="box"] +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Destruction \n n$0=*&this:int** [line 182]\n _=*n$0:int* [line 182]\n _fun_std::std__shared_ptr_~std__shared_ptr(n$0:int**) [line 182]\n " shape="box"] "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" ; +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" [label="4: Call _fun_std::shared_ptr_reset \n n$2=*&this:int** [line 182]\n _=*n$2:int* [line 182]\n _fun_std::shared_ptr_reset(n$2:int**,null:int*) [line 182]\n " shape="box"] + + + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; "reset#shared_ptr#std#(_ZNSt3__110shared_ptrIiE5resetIivEEvPT_).a1205b56a9f5cca1b1c1504f3db46c6e_1" [label="1: Start std::shared_ptr_reset\nFormals: this:int** p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 234]\n " color=yellow style=filled] diff --git a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_root.cpp.dot b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_root.cpp.dot index 67823c5f8..645d73779 100644 --- a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_root.cpp.dot +++ b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_root.cpp.dot @@ -210,14 +210,18 @@ digraph iCFG { "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" [label="1: Start std::shared_ptr_~shared_ptr\nFormals: this:int**\nLocals: \n DECLARE_LOCALS(&return); [line 182]\n " color=yellow style=filled] - "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" ; "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" [label="2: Exit std::shared_ptr_~shared_ptr \n " color=yellow style=filled] -"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Call _fun_std::shared_ptr_reset \n n$1=*&this:int** [line 182]\n _=*n$1:int* [line 182]\n _fun_std::shared_ptr_reset(n$1:int**,null:int*) [line 182]\n " shape="box"] +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Destruction \n n$0=*&this:int** [line 182]\n _=*n$0:int* [line 182]\n _fun_std::std__shared_ptr_~std__shared_ptr(n$0:int**) [line 182]\n " shape="box"] "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" ; +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" [label="4: Call _fun_std::shared_ptr_reset \n n$2=*&this:int** [line 182]\n _=*n$2:int* [line 182]\n _fun_std::shared_ptr_reset(n$2:int**,null:int*) [line 182]\n " shape="box"] + + + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; "reset#shared_ptr#std#(_ZNSt3__110shared_ptrIiE5resetIivEEvPT_).a1205b56a9f5cca1b1c1504f3db46c6e_1" [label="1: Start std::shared_ptr_reset\nFormals: this:int** p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 234]\n " color=yellow style=filled] diff --git a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_symlink.cpp.dot b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_symlink.cpp.dot index 67823c5f8..645d73779 100644 --- a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_symlink.cpp.dot +++ b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_default_symlink.cpp.dot @@ -210,14 +210,18 @@ digraph iCFG { "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" [label="1: Start std::shared_ptr_~shared_ptr\nFormals: this:int**\nLocals: \n DECLARE_LOCALS(&return); [line 182]\n " color=yellow style=filled] - "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" ; "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" [label="2: Exit std::shared_ptr_~shared_ptr \n " color=yellow style=filled] -"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Call _fun_std::shared_ptr_reset \n n$1=*&this:int** [line 182]\n _=*n$1:int* [line 182]\n _fun_std::shared_ptr_reset(n$1:int**,null:int*) [line 182]\n " shape="box"] +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Destruction \n n$0=*&this:int** [line 182]\n _=*n$0:int* [line 182]\n _fun_std::std__shared_ptr_~std__shared_ptr(n$0:int**) [line 182]\n " shape="box"] "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" ; +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" [label="4: Call _fun_std::shared_ptr_reset \n n$2=*&this:int** [line 182]\n _=*n$2:int* [line 182]\n _fun_std::shared_ptr_reset(n$2:int**,null:int*) [line 182]\n " shape="box"] + + + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; "reset#shared_ptr#std#(_ZNSt3__110shared_ptrIiE5resetIivEEvPT_).a1205b56a9f5cca1b1c1504f3db46c6e_1" [label="1: Start std::shared_ptr_reset\nFormals: this:int** p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 234]\n " color=yellow style=filled] diff --git a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_symlink.cpp.dot b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_symlink.cpp.dot index 67823c5f8..645d73779 100644 --- a/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_symlink.cpp.dot +++ b/infer/tests/build_systems/codetoanalyze/clang_translation/src/main_symlink.cpp.dot @@ -210,14 +210,18 @@ digraph iCFG { "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" [label="1: Start std::shared_ptr_~shared_ptr\nFormals: this:int**\nLocals: \n DECLARE_LOCALS(&return); [line 182]\n " color=yellow style=filled] - "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_1" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" ; "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" [label="2: Exit std::shared_ptr_~shared_ptr \n " color=yellow style=filled] -"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Call _fun_std::shared_ptr_reset \n n$1=*&this:int** [line 182]\n _=*n$1:int* [line 182]\n _fun_std::shared_ptr_reset(n$1:int**,null:int*) [line 182]\n " shape="box"] +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" [label="3: Destruction \n n$0=*&this:int** [line 182]\n _=*n$0:int* [line 182]\n _fun_std::std__shared_ptr_~std__shared_ptr(n$0:int**) [line 182]\n " shape="box"] "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_2" ; +"~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" [label="4: Call _fun_std::shared_ptr_reset \n n$2=*&this:int** [line 182]\n _=*n$2:int* [line 182]\n _fun_std::shared_ptr_reset(n$2:int**,null:int*) [line 182]\n " shape="box"] + + + "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_4" -> "~shared_ptr#shared_ptr#std#(_ZNSt3__110shared_ptrIiED0Ev).64f04c4b2ed4a174cbcd135fb2e0998b_3" ; "reset#shared_ptr#std#(_ZNSt3__110shared_ptrIiE5resetIivEEvPT_).a1205b56a9f5cca1b1c1504f3db46c6e_1" [label="1: Start std::shared_ptr_reset\nFormals: this:int** p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 234]\n " color=yellow style=filled] diff --git a/infer/tests/codetoanalyze/cpp/frontend/destructors/destructor_bases.cpp b/infer/tests/codetoanalyze/cpp/frontend/destructors/destructor_bases.cpp new file mode 100644 index 000000000..739d67104 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/frontend/destructors/destructor_bases.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +struct A { + A(){}; + ~A(){}; +}; + +struct B : A { + B(){}; + ~B(){}; +}; + +struct C { + C(){}; + ~C(){}; +}; + +struct D : A, C { + B b; + D(){}; + ~D() { A a; }; +}; + +struct E : B, C, D { + E(){}; + ~E(){}; +}; diff --git a/infer/tests/codetoanalyze/cpp/frontend/destructors/destructor_bases.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/destructors/destructor_bases.cpp.dot new file mode 100644 index 000000000..b80225896 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/frontend/destructors/destructor_bases.cpp.dot @@ -0,0 +1,121 @@ +/* @generated */ +digraph iCFG { +"A#A#{_ZN1AC1Ev}.2d3ff9efa1bcbece3182f08e3514d828_1" [label="1: Start A_A\nFormals: this:A*\nLocals: \n DECLARE_LOCALS(&return); [line 11]\n " color=yellow style=filled] + + + "A#A#{_ZN1AC1Ev}.2d3ff9efa1bcbece3182f08e3514d828_1" -> "A#A#{_ZN1AC1Ev}.2d3ff9efa1bcbece3182f08e3514d828_2" ; +"A#A#{_ZN1AC1Ev}.2d3ff9efa1bcbece3182f08e3514d828_2" [label="2: Exit A_A \n " color=yellow style=filled] + + +"~A#A#(_ZN1AD0Ev).56ee06aef571dbbd330acc7aac738fb2_1" [label="1: Start A_~A\nFormals: this:A*\nLocals: \n DECLARE_LOCALS(&return); [line 12]\n " color=yellow style=filled] + + + "~A#A#(_ZN1AD0Ev).56ee06aef571dbbd330acc7aac738fb2_1" -> "~A#A#(_ZN1AD0Ev).56ee06aef571dbbd330acc7aac738fb2_2" ; +"~A#A#(_ZN1AD0Ev).56ee06aef571dbbd330acc7aac738fb2_2" [label="2: Exit A_~A \n " color=yellow style=filled] + + +"B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_1" [label="1: Start B_B\nFormals: this:B*\nLocals: \n DECLARE_LOCALS(&return); [line 16]\n " color=yellow style=filled] + + + "B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_1" -> "B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_3" ; +"B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_2" [label="2: Exit B_B \n " color=yellow style=filled] + + +"B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_3" [label="3: Constructor Init \n n$0=*&this:B* [line 16]\n _fun_A_A(n$0:B*) [line 16]\n " shape="box"] + + + "B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_3" -> "B#B#{_ZN1BC1Ev}.7d36f8f9e357133df32509b5d80a4f1d_2" ; +"~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_1" [label="1: Start B_~B\nFormals: this:B*\nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled] + + + "~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_1" -> "~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_3" ; +"~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_2" [label="2: Exit B_~B \n " color=yellow style=filled] + + +"~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_3" [label="3: Destruction \n n$0=*&this:B* [line 17]\n _=*n$0:B [line 17]\n _fun_A_~A(n$0:B*) [line 17]\n " shape="box"] + + + "~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_3" -> "~B#B#(_ZN1BD0Ev).cd4fb9d54ed1b3496d9539c455e8ee1d_2" ; +"C#C#{_ZN1CC1Ev}.3e03405a28565a3b8cdc219c868b91d4_1" [label="1: Start C_C\nFormals: this:C*\nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled] + + + "C#C#{_ZN1CC1Ev}.3e03405a28565a3b8cdc219c868b91d4_1" -> "C#C#{_ZN1CC1Ev}.3e03405a28565a3b8cdc219c868b91d4_2" ; +"C#C#{_ZN1CC1Ev}.3e03405a28565a3b8cdc219c868b91d4_2" [label="2: Exit C_C \n " color=yellow style=filled] + + +"~C#C#(_ZN1CD0Ev).5004cab30e9be2ae0ac437333f531054_1" [label="1: Start C_~C\nFormals: this:C*\nLocals: \n DECLARE_LOCALS(&return); [line 22]\n " color=yellow style=filled] + + + "~C#C#(_ZN1CD0Ev).5004cab30e9be2ae0ac437333f531054_1" -> "~C#C#(_ZN1CD0Ev).5004cab30e9be2ae0ac437333f531054_2" ; +"~C#C#(_ZN1CD0Ev).5004cab30e9be2ae0ac437333f531054_2" [label="2: Exit C_~C \n " color=yellow style=filled] + + +"D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_1" [label="1: Start D_D\nFormals: this:D*\nLocals: \n DECLARE_LOCALS(&return); [line 27]\n " color=yellow style=filled] + + + "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_1" -> "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_5" ; +"D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_2" [label="2: Exit D_D \n " color=yellow style=filled] + + +"D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_3" [label="3: Constructor Init \n n$0=*&this:D* [line 27]\n _fun_B_B(n$0.b:B*) [line 27]\n " shape="box"] + + + "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_3" -> "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_2" ; +"D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_4" [label="4: Constructor Init \n n$1=*&this:D* [line 27]\n _fun_C_C(n$1:D*) [line 27]\n " shape="box"] + + + "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_4" -> "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_3" ; +"D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_5" [label="5: Constructor Init \n n$2=*&this:D* [line 27]\n _fun_A_A(n$2:D*) [line 27]\n " shape="box"] + + + "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_5" -> "D#D#{_ZN1DC1Ev}.1fb38ad288cb592a49d11e238b53d161_4" ; +"~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_1" [label="1: Start D_~D\nFormals: this:D*\nLocals: a:A \n DECLARE_LOCALS(&return,&a); [line 28]\n " color=yellow style=filled] + + + "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_1" -> "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_5" ; +"~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_2" [label="2: Exit D_~D \n " color=yellow style=filled] + + +"~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_3" [label="3: Destruction \n n$0=*&this:D* [line 28]\n _=*n$0.b:B [line 28]\n _fun_B_~B(n$0.b:B*) [line 28]\n _=*n$0:D [line 28]\n _fun_C_~C(n$0:D*) [line 28]\n _=*n$0:D [line 28]\n _fun_A_~A(n$0:D*) [line 28]\n " shape="box"] + + + "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_3" -> "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_2" ; +"~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_4" [label="4: Destruction \n _=*&a:A [line 28]\n _fun_A_~A(&a:A*) [line 28]\n " shape="box"] + + + "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_4" -> "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_3" ; +"~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_5" [label="5: DeclStmt \n _fun_A_A(&a:A*) [line 28]\n " shape="box"] + + + "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_5" -> "~D#D#(_ZN1DD0Ev).927ae640f732cd5172d9f1a635578398_4" ; +"E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_1" [label="1: Start E_E\nFormals: this:E*\nLocals: \n DECLARE_LOCALS(&return); [line 32]\n " color=yellow style=filled] + + + "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_1" -> "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_5" ; +"E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_2" [label="2: Exit E_E \n " color=yellow style=filled] + + +"E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_3" [label="3: Constructor Init \n n$0=*&this:E* [line 32]\n _fun_D_D(n$0:E*) [line 32]\n " shape="box"] + + + "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_3" -> "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_2" ; +"E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_4" [label="4: Constructor Init \n n$1=*&this:E* [line 32]\n _fun_C_C(n$1:E*) [line 32]\n " shape="box"] + + + "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_4" -> "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_3" ; +"E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_5" [label="5: Constructor Init \n n$2=*&this:E* [line 32]\n _fun_B_B(n$2:E*) [line 32]\n " shape="box"] + + + "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_5" -> "E#E#{_ZN1EC1Ev}.8eb6f0809ed40dd2a68db058b9bc4ade_4" ; +"~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_1" [label="1: Start E_~E\nFormals: this:E*\nLocals: \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] + + + "~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_1" -> "~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_3" ; +"~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_2" [label="2: Exit E_~E \n " color=yellow style=filled] + + +"~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_3" [label="3: Destruction \n n$0=*&this:E* [line 33]\n _=*n$0:E [line 33]\n _fun_D_~D(n$0:E*) [line 33]\n _=*n$0:E [line 33]\n _fun_C_~C(n$0:E*) [line 33]\n _=*n$0:E [line 33]\n _fun_B_~B(n$0:E*) [line 33]\n " shape="box"] + + + "~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_3" -> "~E#E#(_ZN1ED0Ev).44fb1076af1709dabd7a40484ef7ca13_2" ; +}