From 453924f3037313942a5d6311cd471e90ee9e954f Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Tue, 20 Oct 2015 07:37:13 -0700 Subject: [PATCH] Add basic translation of constructors Summary: public Adds incomplete translation of constructor bodies. Treat constructors as methods with something 'extra'. We still don't translate initializer lists, just pass the information to cTrans where it's ignored Reviewed By: dulmarod Differential Revision: D2550214 fb-gh-sync-id: 102c13a --- infer/src/clang/cAstProcessor.ml | 1 + infer/src/clang/cFrontend.ml | 3 +- infer/src/clang/cMethod_decl.ml | 2 +- infer/src/clang/cMethod_trans.ml | 12 +- infer/src/clang/cModule_type.ml | 5 +- infer/src/clang/cTrans.ml | 4 +- infer/src/clang/cTypes_decl.ml | 5 +- .../c/frontend/nestedoperators/union.cpp | 1 + .../c/frontend/nestedoperators/union.cpp.dot | 36 ++ .../constructors/constructor_with_body.cpp | 26 ++ .../constructor_with_body.cpp.dot | 47 +++ .../cpp/frontend/namespace/namespace.cpp.dot | 41 +- .../member_access_from_return.cpp.dot | 55 +-- .../reference/reference_struct_e2e.cpp.dot | 383 +++++++++--------- .../cpp/frontend/types/inheritance.cpp.dot | 56 ++- .../tests/frontend/cpp/ConstructorsTest.java | 38 ++ .../frontend/cpp/NestedOperatorsTest.java | 4 +- 17 files changed, 466 insertions(+), 253 deletions(-) create mode 120000 infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp create mode 100644 infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot create mode 100644 infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp create mode 100644 infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot create mode 100644 infer/tests/frontend/cpp/ConstructorsTest.java diff --git a/infer/src/clang/cAstProcessor.ml b/infer/src/clang/cAstProcessor.ml index f30fd8e8f..33a7158c9 100644 --- a/infer/src/clang/cAstProcessor.ml +++ b/infer/src/clang/cAstProcessor.ml @@ -269,6 +269,7 @@ and decl_process_locs loc_composer decl = match decl' with | FunctionDecl fun_info -> FunctionDecl (get_updated_fun_decl fun_info) | CXXMethodDecl meth_info -> CXXMethodDecl (get_updated_method_decl meth_info) + | CXXConstructorDecl meth_info -> CXXConstructorDecl (get_updated_method_decl meth_info) | ObjCMethodDecl (decl_info', name, obj_c_method_decl_info) -> let body' = Option.map (stmt_process_locs loc_composer) obj_c_method_decl_info.omdi_body in diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index a240f2c51..4f1ce10c0 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -75,7 +75,8 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = let curr_class = ObjcInterface_decl.interface_impl_declaration tenv name decl_list idi in CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list - | CXXMethodDecl(decl_info, name_info, type_ptr, function_decl_info, _) -> + | CXXMethodDecl (decl_info, name_info, type_ptr, function_decl_info, _) + | CXXConstructorDecl (decl_info, name_info, type_ptr, function_decl_info, _) -> (* di_parent_pointer has pointer to lexical context such as class.*) (* If it's not defined, then it's the same as parent in AST *) let class_decl = match decl_info.Clang_ast_t.di_parent_pointer with diff --git a/infer/src/clang/cMethod_decl.ml b/infer/src/clang/cMethod_decl.ml index 1630cedad..e56b7285f 100644 --- a/infer/src/clang/cMethod_decl.ml +++ b/infer/src/clang/cMethod_decl.ml @@ -103,7 +103,7 @@ struct let rec process_one_method_decl tenv cg cfg curr_class namespace dec = let open Clang_ast_t in match dec with - | CXXMethodDecl _ -> + | CXXMethodDecl _ | CXXConstructorDecl _ -> process_method_decl tenv cg cfg namespace curr_class dec ~is_objc:false | ObjCMethodDecl _ -> process_method_decl tenv cg cfg namespace curr_class dec ~is_objc:true diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 6ee176408..09072820b 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -104,6 +104,10 @@ let get_assume_not_null_calls ms param_decls = | _ -> [] in IList.flatten (IList.map do_one_param param_decls) +let get_init_list_instrs method_decl_info = + let create_custom_instr construct_instr = `CXXConstructorInit construct_instr in + IList.map create_custom_instr method_decl_info.Clang_ast_t.xmdi_cxx_ctor_initializers + let method_signature_of_decl class_name_opt meth_decl block_data_opt = let open Clang_ast_t in match meth_decl, block_data_opt, class_name_opt with @@ -116,13 +120,15 @@ let method_signature_of_decl class_name_opt meth_decl block_data_opt = let ms = build_method_signature decl_info procname func_decl false false in let extra_instrs = get_assume_not_null_calls ms fdi.Clang_ast_t.fdi_parameters in ms, fdi.Clang_ast_t.fdi_body, extra_instrs - | CXXMethodDecl (decl_info, name_info, tp, fdi, _), _, Some class_name -> + | CXXMethodDecl (decl_info, name_info, tp, fdi, mdi), _, Some class_name + | CXXConstructorDecl (decl_info, name_info, tp, fdi, mdi), _, Some class_name -> let method_name = name_info.Clang_ast_t.ni_name in let procname = General_utils.mk_procname_from_cpp_method class_name method_name tp in let method_decl = Cpp_Meth_decl_info (fdi, class_name, tp) in let ms = build_method_signature decl_info procname method_decl false false in - let extra_instrs = get_assume_not_null_calls ms fdi.Clang_ast_t.fdi_parameters in - ms, fdi.Clang_ast_t.fdi_body, extra_instrs + let non_null_instrs = get_assume_not_null_calls ms fdi.Clang_ast_t.fdi_parameters in + let init_list_instrs = get_init_list_instrs mdi in (* it will be empty for methods *) + ms, fdi.Clang_ast_t.fdi_body, (init_list_instrs @ non_null_instrs) | ObjCMethodDecl (decl_info, name_info, mdi), _, Some class_name -> let method_name = name_info.ni_name in let is_instance = mdi.omdi_is_instance_method in diff --git a/infer/src/clang/cModule_type.ml b/infer/src/clang/cModule_type.ml index 53549400c..de4ac331e 100644 --- a/infer/src/clang/cModule_type.ml +++ b/infer/src/clang/cModule_type.ml @@ -9,7 +9,10 @@ type block_data = CContext.t * Clang_ast_t.type_ptr * Procname.t * (Mangled.t * Sil.typ * bool) list -type instr_type = [ `ClangStmt of Clang_ast_t.stmt ] +type instr_type = [ + | `ClangStmt of Clang_ast_t.stmt + | `CXXConstructorInit of Clang_ast_t.cxx_ctor_initializer +] module type CTranslation = sig diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 4dc6580ac..9b0b124b5 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -2076,8 +2076,10 @@ struct IList.map instruction' stmt_list and get_custom_stmt_trans custom_stmts = + (* TODO write translate function for cxx constructor exprs *) let do_one_stmt stmt = match stmt with - | `ClangStmt stmt -> get_clang_stmt_trans [stmt] in + | `ClangStmt stmt -> get_clang_stmt_trans [stmt] + | `CXXConstructorInit instr -> [] in IList.flatten (IList.map do_one_stmt custom_stmts) (** Given a translation state, this function translates a list of clang statements. *) diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index 9add18735..9ee5ae078 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -101,7 +101,7 @@ let get_record_name decl = snd (get_record_name_csu decl) let get_method_decls parent decl_list = let open Clang_ast_t in let rec traverse_decl parent decl = match decl with - | CXXMethodDecl _ -> [(parent, decl)] + | CXXMethodDecl _ | CXXConstructorDecl _ -> [(parent, decl)] | CXXRecordDecl (_, _, _, _, decl_list', _, _, _) | RecordDecl (_, _, _, _, decl_list', _, _) -> traverse_decl_list decl decl_list' | _ -> [] @@ -110,7 +110,8 @@ let get_method_decls parent decl_list = let get_class_methods tenv class_name namespace decl_list = let process_method_decl = function - | Clang_ast_t.CXXMethodDecl (decl_info, name_info, tp, function_decl_info, _) -> + | Clang_ast_t.CXXMethodDecl (decl_info, name_info, tp, function_decl_info, _) + | Clang_ast_t.CXXConstructorDecl (decl_info, name_info, tp, 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 tp in diff --git a/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp b/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp new file mode 120000 index 000000000..4aa4c6033 --- /dev/null +++ b/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp @@ -0,0 +1 @@ +union.c \ No newline at end of file diff --git a/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot b/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot new file mode 100644 index 000000000..06f3c2948 --- /dev/null +++ b/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot @@ -0,0 +1,36 @@ +digraph iCFG { +9 [label="9: BinaryOperatorStmt: Assign \n n$3=*&#GB$x:struct (anonymous at infer_tests_codetoanalyze_c_frontend_nestedoperators_union.cpp:12:1) * [line 27]\n *n$3.a:int =1 [line 27]\n REMOVE_TEMPS(n$3); [line 27]\n " shape="box"] + + + 9 -> 8 ; +8 [label="8: BinaryOperatorStmt: Assign \n *&#GB$y.f:int =7 [line 28]\n " shape="box"] + + + 8 -> 7 ; +7 [label="7: BinaryOperatorStmt: Assign \n n$2=*&#GB$y.f:int [line 29]\n *&#GB$y.g.u:int =n$2 [line 29]\n REMOVE_TEMPS(n$2); [line 29]\n " shape="box"] + + + 7 -> 6 ; +6 [label="6: BinaryOperatorStmt: Assign \n n$0=*&#GB$x:struct (anonymous at infer_tests_codetoanalyze_c_frontend_nestedoperators_union.cpp:12:1) * [line 31]\n n$1=*n$0.b:int [line 31]\n *&#GB$y.g.w:int =n$1 [line 31]\n REMOVE_TEMPS(n$0,n$1); [line 31]\n " shape="box"] + + + 6 -> 5 ; +5 [label="5: Return Stmt \n *&return:int =0 [line 32]\n APPLY_ABSTRACTION; [line 32]\n " shape="box"] + + + 5 -> 4 ; +4 [label="4: Exit main \n " color=yellow style=filled] + + +3 [label="3: Start main\nFormals: \nLocals: l:int \n DECLARE_LOCALS(&return,&l); [line 24]\n NULLIFY(&l,false); [line 24]\n " color=yellow style=filled] + + + 3 -> 9 ; +2 [label="2: Exit (anonymous at infer_tests_codetoanalyze_c_frontend_nestedoperators_union.cpp:14:1)_ \n " color=yellow style=filled] + + +1 [label="1: Start (anonymous at infer_tests_codetoanalyze_c_frontend_nestedoperators_union.cpp:14:1)_\nFormals: this:class (anonymous at infer_tests_codetoanalyze_c_frontend_nestedoperators_union.cpp:14:1) *\nLocals: \n DECLARE_LOCALS(&return); [line 14]\n NULLIFY(&this,false); [line 14]\n " color=yellow style=filled] + + + 1 -> 2 ; +} diff --git a/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp new file mode 100644 index 000000000..78d7d01a5 --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2015 - present Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ + +class X { + int f; + void init() { f = 0;} +public: + X() { + init(); + f = 3; + } + + X(int a, int b); +}; + +X::X(int a, int b) { + int c = a + b; + init(); + f = c; +} diff --git a/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot new file mode 100644 index 000000000..bbdda63bd --- /dev/null +++ b/infer/tests/codetoanalyze/cpp/frontend/constructors/constructor_with_body.cpp.dot @@ -0,0 +1,47 @@ +digraph iCFG { +12 [label="12: DeclStmt \n n$3=*&a:int [line 23]\n n$4=*&b:int [line 23]\n *&c:int =(n$3 + n$4) [line 23]\n REMOVE_TEMPS(n$3,n$4); [line 23]\n NULLIFY(&a,false); [line 23]\n NULLIFY(&b,false); [line 23]\n " shape="box"] + + + 12 -> 11 ; +11 [label="11: Call _fun_X_init \n n$2=*&this:class X * [line 24]\n _fun_X_init(n$2:class X ) [line 24]\n REMOVE_TEMPS(n$2); [line 24]\n " shape="box"] + + + 11 -> 10 ; +10 [label="10: BinaryOperatorStmt: Assign \n n$0=*&this:class X * [line 25]\n n$1=*&c:int [line 25]\n *n$0.f:int =n$1 [line 25]\n REMOVE_TEMPS(n$0,n$1); [line 25]\n NULLIFY(&c,false); [line 25]\n NULLIFY(&this,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"] + + + 10 -> 9 ; +9 [label="9: Exit X_X \n " color=yellow style=filled] + + +8 [label="8: Start X_X\nFormals: this:class X * a:int b:int \nLocals: c:int \n DECLARE_LOCALS(&return,&c); [line 22]\n NULLIFY(&c,false); [line 22]\n " color=yellow style=filled] + + + 8 -> 12 ; +7 [label="7: Call _fun_X_init \n n$1=*&this:class X * [line 15]\n _fun_X_init(n$1:class X ) [line 15]\n REMOVE_TEMPS(n$1); [line 15]\n " shape="box"] + + + 7 -> 6 ; +6 [label="6: BinaryOperatorStmt: Assign \n n$0=*&this:class X * [line 16]\n *n$0.f:int =3 [line 16]\n REMOVE_TEMPS(n$0); [line 16]\n NULLIFY(&this,false); [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] + + + 6 -> 5 ; +5 [label="5: Exit X_X \n " color=yellow style=filled] + + +4 [label="4: Start X_X\nFormals: this:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 14]\n " color=yellow style=filled] + + + 4 -> 7 ; +3 [label="3: BinaryOperatorStmt: Assign \n n$0=*&this:class X * [line 12]\n *n$0.f:int =0 [line 12]\n REMOVE_TEMPS(n$0); [line 12]\n NULLIFY(&this,false); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"] + + + 3 -> 2 ; +2 [label="2: Exit X_init \n " color=yellow style=filled] + + +1 [label="1: Start X_init\nFormals: this:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 12]\n " color=yellow style=filled] + + + 1 -> 3 ; +} diff --git a/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot index 763f3a31e..0ff600f0f 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot @@ -1,24 +1,45 @@ digraph iCFG { -6 [label="6: Return Stmt \n n$0=*&#GB$pi:double [line 29]\n *&return:double =(2 * n$0) [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] +12 [label="12: Exit bar::Rectangle_Rectangle \n " color=yellow style=filled] - 6 -> 5 ; -5 [label="5: Exit value \n " color=yellow style=filled] +11 [label="11: Start bar::Rectangle_Rectangle\nFormals: this:class bar::Rectangle *\nLocals: \n DECLARE_LOCALS(&return); [line 31]\n NULLIFY(&this,false); [line 31]\n " color=yellow style=filled] -4 [label="4: Start value\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] + 11 -> 12 ; +10 [label="10: Return Stmt \n n$0=*&#GB$pi:double [line 29]\n *&return:double =(2 * n$0) [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"] - 4 -> 6 ; -3 [label="3: Return Stmt \n *&return:int =5 [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] + 10 -> 9 ; +9 [label="9: Exit value \n " color=yellow style=filled] - 3 -> 2 ; -2 [label="2: Exit value \n " color=yellow style=filled] +8 [label="8: Start value\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] -1 [label="1: Start value\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 16]\n " color=yellow style=filled] + 8 -> 10 ; +7 [label="7: Exit foo::Rectangle_Rectangle \n " color=yellow style=filled] - 1 -> 3 ; +6 [label="6: Start foo::Rectangle_Rectangle\nFormals: this:class foo::Rectangle *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n NULLIFY(&this,false); [line 18]\n " color=yellow style=filled] + + + 6 -> 7 ; +5 [label="5: Return Stmt \n *&return:int =5 [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] + + + 5 -> 4 ; +4 [label="4: Exit value \n " color=yellow style=filled] + + +3 [label="3: Start value\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 16]\n " color=yellow style=filled] + + + 3 -> 5 ; +2 [label="2: Exit foo::foo::my_record_ \n " color=yellow style=filled] + + +1 [label="1: Start foo::foo::my_record_\nFormals: this:class foo::foo::my_record *\nLocals: \n DECLARE_LOCALS(&return); [line 15]\n NULLIFY(&this,false); [line 15]\n " color=yellow style=filled] + + + 1 -> 2 ; } diff --git a/infer/tests/codetoanalyze/cpp/frontend/reference/member_access_from_return.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/reference/member_access_from_return.cpp.dot index a13ebee02..121a65cea 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/reference/member_access_from_return.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/reference/member_access_from_return.cpp.dot @@ -1,56 +1,63 @@ digraph iCFG { -17 [label="17: DeclStmt \n n$2=_fun_get_ptr() [line 25]\n n$3=*n$2.f:int [line 25]\n *&f:int =n$3 [line 25]\n REMOVE_TEMPS(n$2,n$3); [line 25]\n NULLIFY(&f,false); [line 25]\n " shape="box"] +19 [label="19: DeclStmt \n n$2=_fun_get_ptr() [line 25]\n n$3=*n$2.f:int [line 25]\n *&f:int =n$3 [line 25]\n REMOVE_TEMPS(n$2,n$3); [line 25]\n NULLIFY(&f,false); [line 25]\n " shape="box"] - 17 -> 16 ; -16 [label="16: DeclStmt \n n$0=_fun_get_ptr() [line 26]\n n$1=_fun_X_call(n$0:class X ) [line 26]\n *&c:int =n$1 [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&c,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] + 19 -> 18 ; +18 [label="18: DeclStmt \n n$0=_fun_get_ptr() [line 26]\n n$1=_fun_X_call(n$0:class X ) [line 26]\n *&c:int =n$1 [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&c,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] - 16 -> 15 ; -15 [label="15: Exit test_ptr \n " color=yellow style=filled] + 18 -> 17 ; +17 [label="17: Exit test_ptr \n " color=yellow style=filled] -14 [label="14: Start test_ptr\nFormals: \nLocals: c:int f:int \n DECLARE_LOCALS(&return,&c,&f); [line 24]\n NULLIFY(&c,false); [line 24]\n NULLIFY(&f,false); [line 24]\n " color=yellow style=filled] +16 [label="16: Start test_ptr\nFormals: \nLocals: c:int f:int \n DECLARE_LOCALS(&return,&c,&f); [line 24]\n NULLIFY(&c,false); [line 24]\n NULLIFY(&f,false); [line 24]\n " color=yellow style=filled] - 14 -> 17 ; -13 [label="13: DeclStmt \n n$2=_fun_get_ref() [line 20]\n n$3=*n$2.f:int [line 20]\n *&f:int =n$3 [line 20]\n REMOVE_TEMPS(n$2,n$3); [line 20]\n NULLIFY(&f,false); [line 20]\n " shape="box"] + 16 -> 19 ; +15 [label="15: DeclStmt \n n$2=_fun_get_ref() [line 20]\n n$3=*n$2.f:int [line 20]\n *&f:int =n$3 [line 20]\n REMOVE_TEMPS(n$2,n$3); [line 20]\n NULLIFY(&f,false); [line 20]\n " shape="box"] - 13 -> 12 ; -12 [label="12: DeclStmt \n n$0=_fun_get_ref() [line 21]\n n$1=_fun_X_call(n$0:class X ) [line 21]\n *&c:int =n$1 [line 21]\n REMOVE_TEMPS(n$0,n$1); [line 21]\n NULLIFY(&c,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] + 15 -> 14 ; +14 [label="14: DeclStmt \n n$0=_fun_get_ref() [line 21]\n n$1=_fun_X_call(n$0:class X ) [line 21]\n *&c:int =n$1 [line 21]\n REMOVE_TEMPS(n$0,n$1); [line 21]\n NULLIFY(&c,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] - 12 -> 11 ; -11 [label="11: Exit test_ref \n " color=yellow style=filled] + 14 -> 13 ; +13 [label="13: Exit test_ref \n " color=yellow style=filled] -10 [label="10: Start test_ref\nFormals: \nLocals: c:int f:int \n DECLARE_LOCALS(&return,&c,&f); [line 19]\n NULLIFY(&c,false); [line 19]\n NULLIFY(&f,false); [line 19]\n " color=yellow style=filled] +12 [label="12: Start test_ref\nFormals: \nLocals: c:int f:int \n DECLARE_LOCALS(&return,&c,&f); [line 19]\n NULLIFY(&c,false); [line 19]\n NULLIFY(&f,false); [line 19]\n " color=yellow style=filled] - 10 -> 13 ; -9 [label="9: Return Stmt \n *&return:class X &=&#GB$global [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] + 12 -> 15 ; +11 [label="11: Return Stmt \n *&return:class X &=&#GB$global [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] - 9 -> 8 ; -8 [label="8: Exit get_ref \n " color=yellow style=filled] + 11 -> 10 ; +10 [label="10: Exit get_ref \n " color=yellow style=filled] -7 [label="7: Start get_ref\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled] +9 [label="9: Start get_ref\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled] - 7 -> 9 ; -6 [label="6: Return Stmt \n *&return:class X *=&#GB$global [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] + 9 -> 11 ; +8 [label="8: Return Stmt \n *&return:class X *=&#GB$global [line 16]\n APPLY_ABSTRACTION; [line 16]\n " shape="box"] - 6 -> 5 ; -5 [label="5: Exit get_ptr \n " color=yellow style=filled] + 8 -> 7 ; +7 [label="7: Exit get_ptr \n " color=yellow style=filled] -4 [label="4: Start get_ptr\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 16]\n " color=yellow style=filled] +6 [label="6: Start get_ptr\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 16]\n " color=yellow style=filled] - 4 -> 6 ; + 6 -> 8 ; +5 [label="5: Exit X_X \n " color=yellow style=filled] + + +4 [label="4: Start X_X\nFormals: this:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 10]\n NULLIFY(&this,false); [line 10]\n " color=yellow style=filled] + + + 4 -> 5 ; 3 [label="3: Return Stmt \n n$0=*&this:class X * [line 12]\n n$1=*n$0.f:int [line 12]\n *&return:int =n$1 [line 12]\n REMOVE_TEMPS(n$0,n$1); [line 12]\n NULLIFY(&this,false); [line 12]\n APPLY_ABSTRACTION; [line 12]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot index 045a3cd88..bbe8a5b8a 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/reference/reference_struct_e2e.cpp.dot @@ -1,416 +1,423 @@ digraph iCFG { -117 [label="117: Call _fun_X_zero \n n$3=_fun_get_global_ref() [line 136]\n _fun_X_zero(n$3:class X ) [line 136]\n REMOVE_TEMPS(n$3); [line 136]\n " shape="box"] +119 [label="119: Call _fun_X_zero \n n$3=_fun_get_global_ref() [line 136]\n _fun_X_zero(n$3:class X ) [line 136]\n REMOVE_TEMPS(n$3); [line 136]\n " shape="box"] + + + 119 -> 118 ; +118 [label="118: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ref() [line 137]\n *n$2.f:int =1 [line 137]\n REMOVE_TEMPS(n$2); [line 137]\n " shape="box"] + + + 118 -> 117 ; +117 [label="117: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 138]\n n$1=_fun_X_div(n$0:class X ) [line 138]\n REMOVE_TEMPS(n$0,n$1); [line 138]\n APPLY_ABSTRACTION; [line 138]\n " shape="box"] 117 -> 116 ; -116 [label="116: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ref() [line 137]\n *n$2.f:int =1 [line 137]\n REMOVE_TEMPS(n$2); [line 137]\n " shape="box"] +116 [label="116: Exit get_global_ref_div1_field \n " color=yellow style=filled] - 116 -> 115 ; -115 [label="115: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 138]\n n$1=_fun_X_div(n$0:class X ) [line 138]\n REMOVE_TEMPS(n$0,n$1); [line 138]\n APPLY_ABSTRACTION; [line 138]\n " shape="box"] +115 [label="115: Start get_global_ref_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 135]\n " color=yellow style=filled] - 115 -> 114 ; -114 [label="114: Exit get_global_ref_div1_field \n " color=yellow style=filled] + 115 -> 119 ; +114 [label="114: Call _fun_X_nonzero \n n$3=_fun_get_global_ref() [line 130]\n _fun_X_nonzero(n$3:class X ) [line 130]\n REMOVE_TEMPS(n$3); [line 130]\n " shape="box"] -113 [label="113: Start get_global_ref_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 135]\n " color=yellow style=filled] + 114 -> 113 ; +113 [label="113: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ref() [line 131]\n *n$2.f:int =0 [line 131]\n REMOVE_TEMPS(n$2); [line 131]\n " shape="box"] - 113 -> 117 ; -112 [label="112: Call _fun_X_nonzero \n n$3=_fun_get_global_ref() [line 130]\n _fun_X_nonzero(n$3:class X ) [line 130]\n REMOVE_TEMPS(n$3); [line 130]\n " shape="box"] + 113 -> 112 ; +112 [label="112: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 132]\n n$1=_fun_X_div(n$0:class X ) [line 132]\n REMOVE_TEMPS(n$0,n$1); [line 132]\n APPLY_ABSTRACTION; [line 132]\n " shape="box"] 112 -> 111 ; -111 [label="111: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ref() [line 131]\n *n$2.f:int =0 [line 131]\n REMOVE_TEMPS(n$2); [line 131]\n " shape="box"] +111 [label="111: Exit get_global_ref_div0_field \n " color=yellow style=filled] - 111 -> 110 ; -110 [label="110: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 132]\n n$1=_fun_X_div(n$0:class X ) [line 132]\n REMOVE_TEMPS(n$0,n$1); [line 132]\n APPLY_ABSTRACTION; [line 132]\n " shape="box"] +110 [label="110: Start get_global_ref_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 129]\n " color=yellow style=filled] - 110 -> 109 ; -109 [label="109: Exit get_global_ref_div0_field \n " color=yellow style=filled] + 110 -> 114 ; +109 [label="109: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 124]\n *n$3.f:int =0 [line 124]\n REMOVE_TEMPS(n$3); [line 124]\n " shape="box"] -108 [label="108: Start get_global_ref_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 129]\n " color=yellow style=filled] + 109 -> 108 ; +108 [label="108: Call _fun_X_nonzero \n n$2=_fun_get_global_ref() [line 125]\n _fun_X_nonzero(n$2:class X ) [line 125]\n REMOVE_TEMPS(n$2); [line 125]\n " shape="box"] - 108 -> 112 ; -107 [label="107: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 124]\n *n$3.f:int =0 [line 124]\n REMOVE_TEMPS(n$3); [line 124]\n " shape="box"] + 108 -> 107 ; +107 [label="107: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 126]\n n$1=_fun_X_div(n$0:class X ) [line 126]\n REMOVE_TEMPS(n$0,n$1); [line 126]\n APPLY_ABSTRACTION; [line 126]\n " shape="box"] 107 -> 106 ; -106 [label="106: Call _fun_X_nonzero \n n$2=_fun_get_global_ref() [line 125]\n _fun_X_nonzero(n$2:class X ) [line 125]\n REMOVE_TEMPS(n$2); [line 125]\n " shape="box"] +106 [label="106: Exit get_global_ref_div1_method \n " color=yellow style=filled] - 106 -> 105 ; -105 [label="105: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 126]\n n$1=_fun_X_div(n$0:class X ) [line 126]\n REMOVE_TEMPS(n$0,n$1); [line 126]\n APPLY_ABSTRACTION; [line 126]\n " shape="box"] +105 [label="105: Start get_global_ref_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 123]\n " color=yellow style=filled] - 105 -> 104 ; -104 [label="104: Exit get_global_ref_div1_method \n " color=yellow style=filled] + 105 -> 109 ; +104 [label="104: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 118]\n *n$3.f:int =1 [line 118]\n REMOVE_TEMPS(n$3); [line 118]\n " shape="box"] -103 [label="103: Start get_global_ref_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 123]\n " color=yellow style=filled] + 104 -> 103 ; +103 [label="103: Call _fun_X_zero \n n$2=_fun_get_global_ref() [line 119]\n _fun_X_zero(n$2:class X ) [line 119]\n REMOVE_TEMPS(n$2); [line 119]\n " shape="box"] - 103 -> 107 ; -102 [label="102: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ref() [line 118]\n *n$3.f:int =1 [line 118]\n REMOVE_TEMPS(n$3); [line 118]\n " shape="box"] + 103 -> 102 ; +102 [label="102: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 120]\n n$1=_fun_X_div(n$0:class X ) [line 120]\n REMOVE_TEMPS(n$0,n$1); [line 120]\n APPLY_ABSTRACTION; [line 120]\n " shape="box"] 102 -> 101 ; -101 [label="101: Call _fun_X_zero \n n$2=_fun_get_global_ref() [line 119]\n _fun_X_zero(n$2:class X ) [line 119]\n REMOVE_TEMPS(n$2); [line 119]\n " shape="box"] +101 [label="101: Exit get_global_ref_div0_method \n " color=yellow style=filled] - 101 -> 100 ; -100 [label="100: Call _fun_X_div \n n$0=_fun_get_global_ref() [line 120]\n n$1=_fun_X_div(n$0:class X ) [line 120]\n REMOVE_TEMPS(n$0,n$1); [line 120]\n APPLY_ABSTRACTION; [line 120]\n " shape="box"] +100 [label="100: Start get_global_ref_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 117]\n " color=yellow style=filled] - 100 -> 99 ; -99 [label="99: Exit get_global_ref_div0_method \n " color=yellow style=filled] + 100 -> 104 ; +99 [label="99: Call _fun_set_field_ref \n n$2=*&x:class X & [line 113]\n _fun_set_field_ref(n$2:class X &,1:int ) [line 113]\n REMOVE_TEMPS(n$2); [line 113]\n " shape="box"] -98 [label="98: Start get_global_ref_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 117]\n " color=yellow style=filled] + 99 -> 98 ; +98 [label="98: Return Stmt \n n$0=*&x:class X & [line 114]\n n$1=_fun_X_div(n$0:class X ) [line 114]\n *&return:int =n$1 [line 114]\n REMOVE_TEMPS(n$0,n$1); [line 114]\n NULLIFY(&x,false); [line 114]\n APPLY_ABSTRACTION; [line 114]\n " shape="box"] - 98 -> 102 ; -97 [label="97: Call _fun_set_field_ref \n n$2=*&x:class X & [line 113]\n _fun_set_field_ref(n$2:class X &,1:int ) [line 113]\n REMOVE_TEMPS(n$2); [line 113]\n " shape="box"] + 98 -> 97 ; +97 [label="97: Exit field_div1_ref \n " color=yellow style=filled] - 97 -> 96 ; -96 [label="96: Return Stmt \n n$0=*&x:class X & [line 114]\n n$1=_fun_X_div(n$0:class X ) [line 114]\n *&return:int =n$1 [line 114]\n REMOVE_TEMPS(n$0,n$1); [line 114]\n NULLIFY(&x,false); [line 114]\n APPLY_ABSTRACTION; [line 114]\n " shape="box"] +96 [label="96: Start field_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 112]\n " color=yellow style=filled] - 96 -> 95 ; -95 [label="95: Exit field_div1_ref \n " color=yellow style=filled] + 96 -> 99 ; +95 [label="95: Call _fun_set_field_ref \n n$2=*&x:class X & [line 108]\n _fun_set_field_ref(n$2:class X &,0:int ) [line 108]\n REMOVE_TEMPS(n$2); [line 108]\n " shape="box"] -94 [label="94: Start field_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 112]\n " color=yellow style=filled] + 95 -> 94 ; +94 [label="94: Return Stmt \n n$0=*&x:class X & [line 109]\n n$1=_fun_X_div(n$0:class X ) [line 109]\n *&return:int =n$1 [line 109]\n REMOVE_TEMPS(n$0,n$1); [line 109]\n NULLIFY(&x,false); [line 109]\n APPLY_ABSTRACTION; [line 109]\n " shape="box"] - 94 -> 97 ; -93 [label="93: Call _fun_set_field_ref \n n$2=*&x:class X & [line 108]\n _fun_set_field_ref(n$2:class X &,0:int ) [line 108]\n REMOVE_TEMPS(n$2); [line 108]\n " shape="box"] + 94 -> 93 ; +93 [label="93: Exit field_div0_ref \n " color=yellow style=filled] - 93 -> 92 ; -92 [label="92: Return Stmt \n n$0=*&x:class X & [line 109]\n n$1=_fun_X_div(n$0:class X ) [line 109]\n *&return:int =n$1 [line 109]\n REMOVE_TEMPS(n$0,n$1); [line 109]\n NULLIFY(&x,false); [line 109]\n APPLY_ABSTRACTION; [line 109]\n " shape="box"] +92 [label="92: Start field_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 107]\n " color=yellow style=filled] - 92 -> 91 ; -91 [label="91: Exit field_div0_ref \n " color=yellow style=filled] + 92 -> 95 ; +91 [label="91: Call _fun_nonzero_ref \n n$2=*&x:class X & [line 103]\n _fun_nonzero_ref(n$2:class X &) [line 103]\n REMOVE_TEMPS(n$2); [line 103]\n " shape="box"] -90 [label="90: Start field_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 107]\n " color=yellow style=filled] + 91 -> 90 ; +90 [label="90: Return Stmt \n n$0=*&x:class X & [line 104]\n n$1=_fun_X_div(n$0:class X ) [line 104]\n *&return:int =n$1 [line 104]\n REMOVE_TEMPS(n$0,n$1); [line 104]\n NULLIFY(&x,false); [line 104]\n APPLY_ABSTRACTION; [line 104]\n " shape="box"] - 90 -> 93 ; -89 [label="89: Call _fun_nonzero_ref \n n$2=*&x:class X & [line 103]\n _fun_nonzero_ref(n$2:class X &) [line 103]\n REMOVE_TEMPS(n$2); [line 103]\n " shape="box"] + 90 -> 89 ; +89 [label="89: Exit method_div1_ref \n " color=yellow style=filled] - 89 -> 88 ; -88 [label="88: Return Stmt \n n$0=*&x:class X & [line 104]\n n$1=_fun_X_div(n$0:class X ) [line 104]\n *&return:int =n$1 [line 104]\n REMOVE_TEMPS(n$0,n$1); [line 104]\n NULLIFY(&x,false); [line 104]\n APPLY_ABSTRACTION; [line 104]\n " shape="box"] +88 [label="88: Start method_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 102]\n " color=yellow style=filled] - 88 -> 87 ; -87 [label="87: Exit method_div1_ref \n " color=yellow style=filled] + 88 -> 91 ; +87 [label="87: Call _fun_zero_ref \n n$2=*&x:class X & [line 98]\n _fun_zero_ref(n$2:class X &) [line 98]\n REMOVE_TEMPS(n$2); [line 98]\n " shape="box"] -86 [label="86: Start method_div1_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 102]\n " color=yellow style=filled] + 87 -> 86 ; +86 [label="86: Return Stmt \n n$0=*&x:class X & [line 99]\n n$1=_fun_X_div(n$0:class X ) [line 99]\n *&return:int =n$1 [line 99]\n REMOVE_TEMPS(n$0,n$1); [line 99]\n NULLIFY(&x,false); [line 99]\n APPLY_ABSTRACTION; [line 99]\n " shape="box"] - 86 -> 89 ; -85 [label="85: Call _fun_zero_ref \n n$2=*&x:class X & [line 98]\n _fun_zero_ref(n$2:class X &) [line 98]\n REMOVE_TEMPS(n$2); [line 98]\n " shape="box"] + 86 -> 85 ; +85 [label="85: Exit method_div0_ref \n " color=yellow style=filled] - 85 -> 84 ; -84 [label="84: Return Stmt \n n$0=*&x:class X & [line 99]\n n$1=_fun_X_div(n$0:class X ) [line 99]\n *&return:int =n$1 [line 99]\n REMOVE_TEMPS(n$0,n$1); [line 99]\n NULLIFY(&x,false); [line 99]\n APPLY_ABSTRACTION; [line 99]\n " shape="box"] +84 [label="84: Start method_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 97]\n " color=yellow style=filled] - 84 -> 83 ; -83 [label="83: Exit method_div0_ref \n " color=yellow style=filled] + 84 -> 87 ; +83 [label="83: Call _fun_X_zero \n n$3=_fun_get_global_ptr() [line 92]\n _fun_X_zero(n$3:class X ) [line 92]\n REMOVE_TEMPS(n$3); [line 92]\n " shape="box"] -82 [label="82: Start method_div0_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 97]\n " color=yellow style=filled] + 83 -> 82 ; +82 [label="82: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ptr() [line 93]\n *n$2.f:int =1 [line 93]\n REMOVE_TEMPS(n$2); [line 93]\n " shape="box"] - 82 -> 85 ; -81 [label="81: Call _fun_X_zero \n n$3=_fun_get_global_ptr() [line 92]\n _fun_X_zero(n$3:class X ) [line 92]\n REMOVE_TEMPS(n$3); [line 92]\n " shape="box"] + 82 -> 81 ; +81 [label="81: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 94]\n n$1=_fun_X_div(n$0:class X ) [line 94]\n REMOVE_TEMPS(n$0,n$1); [line 94]\n APPLY_ABSTRACTION; [line 94]\n " shape="box"] 81 -> 80 ; -80 [label="80: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ptr() [line 93]\n *n$2.f:int =1 [line 93]\n REMOVE_TEMPS(n$2); [line 93]\n " shape="box"] +80 [label="80: Exit get_global_ptr_div1_field \n " color=yellow style=filled] - 80 -> 79 ; -79 [label="79: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 94]\n n$1=_fun_X_div(n$0:class X ) [line 94]\n REMOVE_TEMPS(n$0,n$1); [line 94]\n APPLY_ABSTRACTION; [line 94]\n " shape="box"] +79 [label="79: Start get_global_ptr_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 91]\n " color=yellow style=filled] - 79 -> 78 ; -78 [label="78: Exit get_global_ptr_div1_field \n " color=yellow style=filled] + 79 -> 83 ; +78 [label="78: Call _fun_X_nonzero \n n$3=_fun_get_global_ptr() [line 86]\n _fun_X_nonzero(n$3:class X ) [line 86]\n REMOVE_TEMPS(n$3); [line 86]\n " shape="box"] -77 [label="77: Start get_global_ptr_div1_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 91]\n " color=yellow style=filled] + 78 -> 77 ; +77 [label="77: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ptr() [line 87]\n *n$2.f:int =0 [line 87]\n REMOVE_TEMPS(n$2); [line 87]\n " shape="box"] - 77 -> 81 ; -76 [label="76: Call _fun_X_nonzero \n n$3=_fun_get_global_ptr() [line 86]\n _fun_X_nonzero(n$3:class X ) [line 86]\n REMOVE_TEMPS(n$3); [line 86]\n " shape="box"] + 77 -> 76 ; +76 [label="76: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 88]\n n$1=_fun_X_div(n$0:class X ) [line 88]\n REMOVE_TEMPS(n$0,n$1); [line 88]\n APPLY_ABSTRACTION; [line 88]\n " shape="box"] 76 -> 75 ; -75 [label="75: BinaryOperatorStmt: Assign \n n$2=_fun_get_global_ptr() [line 87]\n *n$2.f:int =0 [line 87]\n REMOVE_TEMPS(n$2); [line 87]\n " shape="box"] +75 [label="75: Exit get_global_ptr_div0_field \n " color=yellow style=filled] - 75 -> 74 ; -74 [label="74: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 88]\n n$1=_fun_X_div(n$0:class X ) [line 88]\n REMOVE_TEMPS(n$0,n$1); [line 88]\n APPLY_ABSTRACTION; [line 88]\n " shape="box"] +74 [label="74: Start get_global_ptr_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 85]\n " color=yellow style=filled] - 74 -> 73 ; -73 [label="73: Exit get_global_ptr_div0_field \n " color=yellow style=filled] + 74 -> 78 ; +73 [label="73: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 80]\n *n$3.f:int =0 [line 80]\n REMOVE_TEMPS(n$3); [line 80]\n " shape="box"] -72 [label="72: Start get_global_ptr_div0_field\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 85]\n " color=yellow style=filled] + 73 -> 72 ; +72 [label="72: Call _fun_X_nonzero \n n$2=_fun_get_global_ptr() [line 81]\n _fun_X_nonzero(n$2:class X ) [line 81]\n REMOVE_TEMPS(n$2); [line 81]\n " shape="box"] - 72 -> 76 ; -71 [label="71: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 80]\n *n$3.f:int =0 [line 80]\n REMOVE_TEMPS(n$3); [line 80]\n " shape="box"] + 72 -> 71 ; +71 [label="71: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 82]\n n$1=_fun_X_div(n$0:class X ) [line 82]\n REMOVE_TEMPS(n$0,n$1); [line 82]\n APPLY_ABSTRACTION; [line 82]\n " shape="box"] 71 -> 70 ; -70 [label="70: Call _fun_X_nonzero \n n$2=_fun_get_global_ptr() [line 81]\n _fun_X_nonzero(n$2:class X ) [line 81]\n REMOVE_TEMPS(n$2); [line 81]\n " shape="box"] +70 [label="70: Exit get_global_ptr_div1_method \n " color=yellow style=filled] - 70 -> 69 ; -69 [label="69: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 82]\n n$1=_fun_X_div(n$0:class X ) [line 82]\n REMOVE_TEMPS(n$0,n$1); [line 82]\n APPLY_ABSTRACTION; [line 82]\n " shape="box"] +69 [label="69: Start get_global_ptr_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 79]\n " color=yellow style=filled] - 69 -> 68 ; -68 [label="68: Exit get_global_ptr_div1_method \n " color=yellow style=filled] + 69 -> 73 ; +68 [label="68: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 74]\n *n$3.f:int =1 [line 74]\n REMOVE_TEMPS(n$3); [line 74]\n " shape="box"] -67 [label="67: Start get_global_ptr_div1_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 79]\n " color=yellow style=filled] + 68 -> 67 ; +67 [label="67: Call _fun_X_zero \n n$2=_fun_get_global_ptr() [line 75]\n _fun_X_zero(n$2:class X ) [line 75]\n REMOVE_TEMPS(n$2); [line 75]\n " shape="box"] - 67 -> 71 ; -66 [label="66: BinaryOperatorStmt: Assign \n n$3=_fun_get_global_ptr() [line 74]\n *n$3.f:int =1 [line 74]\n REMOVE_TEMPS(n$3); [line 74]\n " shape="box"] + 67 -> 66 ; +66 [label="66: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 76]\n n$1=_fun_X_div(n$0:class X ) [line 76]\n REMOVE_TEMPS(n$0,n$1); [line 76]\n APPLY_ABSTRACTION; [line 76]\n " shape="box"] 66 -> 65 ; -65 [label="65: Call _fun_X_zero \n n$2=_fun_get_global_ptr() [line 75]\n _fun_X_zero(n$2:class X ) [line 75]\n REMOVE_TEMPS(n$2); [line 75]\n " shape="box"] +65 [label="65: Exit get_global_ptr_div0_method \n " color=yellow style=filled] - 65 -> 64 ; -64 [label="64: Call _fun_X_div \n n$0=_fun_get_global_ptr() [line 76]\n n$1=_fun_X_div(n$0:class X ) [line 76]\n REMOVE_TEMPS(n$0,n$1); [line 76]\n APPLY_ABSTRACTION; [line 76]\n " shape="box"] +64 [label="64: Start get_global_ptr_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 73]\n " color=yellow style=filled] - 64 -> 63 ; -63 [label="63: Exit get_global_ptr_div0_method \n " color=yellow style=filled] + 64 -> 68 ; +63 [label="63: Call _fun_set_field_ptr \n n$3=*&x:class X * [line 68]\n _fun_set_field_ptr(n$3:class X *,1:int ) [line 68]\n REMOVE_TEMPS(n$3); [line 68]\n " shape="box"] -62 [label="62: Start get_global_ptr_div0_method\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 73]\n " color=yellow style=filled] + 63 -> 62 ; +62 [label="62: Return Stmt \n n$1=*&x:class X * [line 69]\n n$2=_fun_X_div(n$1:class X ) [line 69]\n *&return:int =n$2 [line 69]\n REMOVE_TEMPS(n$1,n$2); [line 69]\n NULLIFY(&x,false); [line 69]\n APPLY_ABSTRACTION; [line 69]\n " shape="box"] - 62 -> 66 ; -61 [label="61: Call _fun_set_field_ptr \n n$3=*&x:class X * [line 68]\n _fun_set_field_ptr(n$3:class X *,1:int ) [line 68]\n REMOVE_TEMPS(n$3); [line 68]\n " shape="box"] + 62 -> 58 ; +61 [label="61: Prune (false branch) \n n$0=*&x:class X * [line 67]\n PRUNE((n$0 == 0), false); [line 67]\n REMOVE_TEMPS(n$0); [line 67]\n " shape="invhouse"] - 61 -> 60 ; -60 [label="60: Return Stmt \n n$1=*&x:class X * [line 69]\n n$2=_fun_X_div(n$1:class X ) [line 69]\n *&return:int =n$2 [line 69]\n REMOVE_TEMPS(n$1,n$2); [line 69]\n NULLIFY(&x,false); [line 69]\n APPLY_ABSTRACTION; [line 69]\n " shape="box"] + 61 -> 59 ; +60 [label="60: Prune (true branch) \n n$0=*&x:class X * [line 67]\n PRUNE((n$0 != 0), true); [line 67]\n REMOVE_TEMPS(n$0); [line 67]\n " shape="invhouse"] - 60 -> 56 ; -59 [label="59: Prune (false branch) \n n$0=*&x:class X * [line 67]\n PRUNE((n$0 == 0), false); [line 67]\n REMOVE_TEMPS(n$0); [line 67]\n " shape="invhouse"] + 60 -> 63 ; +59 [label="59: + \n NULLIFY(&x,false); [line 67]\n " ] - 59 -> 57 ; -58 [label="58: Prune (true branch) \n n$0=*&x:class X * [line 67]\n PRUNE((n$0 != 0), true); [line 67]\n REMOVE_TEMPS(n$0); [line 67]\n " shape="invhouse"] + 59 -> 58 ; +58 [label="58: Exit field_div1_ptr \n " color=yellow style=filled] - 58 -> 61 ; -57 [label="57: + \n NULLIFY(&x,false); [line 67]\n " ] +57 [label="57: Start field_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 66]\n " color=yellow style=filled] - 57 -> 56 ; -56 [label="56: Exit field_div1_ptr \n " color=yellow style=filled] + 57 -> 60 ; + 57 -> 61 ; +56 [label="56: Call _fun_set_field_ptr \n n$3=*&x:class X * [line 61]\n _fun_set_field_ptr(n$3:class X *,0:int ) [line 61]\n REMOVE_TEMPS(n$3); [line 61]\n " shape="box"] -55 [label="55: Start field_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 66]\n " color=yellow style=filled] + 56 -> 55 ; +55 [label="55: Return Stmt \n n$1=*&x:class X * [line 62]\n n$2=_fun_X_div(n$1:class X ) [line 62]\n *&return:int =n$2 [line 62]\n REMOVE_TEMPS(n$1,n$2); [line 62]\n NULLIFY(&x,false); [line 62]\n APPLY_ABSTRACTION; [line 62]\n " shape="box"] - 55 -> 58 ; - 55 -> 59 ; -54 [label="54: Call _fun_set_field_ptr \n n$3=*&x:class X * [line 61]\n _fun_set_field_ptr(n$3:class X *,0:int ) [line 61]\n REMOVE_TEMPS(n$3); [line 61]\n " shape="box"] + 55 -> 51 ; +54 [label="54: Prune (false branch) \n n$0=*&x:class X * [line 60]\n PRUNE((n$0 == 0), false); [line 60]\n REMOVE_TEMPS(n$0); [line 60]\n " shape="invhouse"] - 54 -> 53 ; -53 [label="53: Return Stmt \n n$1=*&x:class X * [line 62]\n n$2=_fun_X_div(n$1:class X ) [line 62]\n *&return:int =n$2 [line 62]\n REMOVE_TEMPS(n$1,n$2); [line 62]\n NULLIFY(&x,false); [line 62]\n APPLY_ABSTRACTION; [line 62]\n " shape="box"] + 54 -> 52 ; +53 [label="53: Prune (true branch) \n n$0=*&x:class X * [line 60]\n PRUNE((n$0 != 0), true); [line 60]\n REMOVE_TEMPS(n$0); [line 60]\n " shape="invhouse"] - 53 -> 49 ; -52 [label="52: Prune (false branch) \n n$0=*&x:class X * [line 60]\n PRUNE((n$0 == 0), false); [line 60]\n REMOVE_TEMPS(n$0); [line 60]\n " shape="invhouse"] + 53 -> 56 ; +52 [label="52: + \n NULLIFY(&x,false); [line 60]\n " ] - 52 -> 50 ; -51 [label="51: Prune (true branch) \n n$0=*&x:class X * [line 60]\n PRUNE((n$0 != 0), true); [line 60]\n REMOVE_TEMPS(n$0); [line 60]\n " shape="invhouse"] + 52 -> 51 ; +51 [label="51: Exit field_div0_ptr \n " color=yellow style=filled] - 51 -> 54 ; -50 [label="50: + \n NULLIFY(&x,false); [line 60]\n " ] +50 [label="50: Start field_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 59]\n " color=yellow style=filled] - 50 -> 49 ; -49 [label="49: Exit field_div0_ptr \n " color=yellow style=filled] + 50 -> 53 ; + 50 -> 54 ; +49 [label="49: Call _fun_nonzero_ptr \n n$3=*&x:class X * [line 54]\n _fun_nonzero_ptr(n$3:class X *) [line 54]\n REMOVE_TEMPS(n$3); [line 54]\n " shape="box"] -48 [label="48: Start field_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 59]\n " color=yellow style=filled] + 49 -> 48 ; +48 [label="48: Return Stmt \n n$1=*&x:class X * [line 55]\n n$2=_fun_X_div(n$1:class X ) [line 55]\n *&return:int =n$2 [line 55]\n REMOVE_TEMPS(n$1,n$2); [line 55]\n NULLIFY(&x,false); [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="box"] - 48 -> 51 ; - 48 -> 52 ; -47 [label="47: Call _fun_nonzero_ptr \n n$3=*&x:class X * [line 54]\n _fun_nonzero_ptr(n$3:class X *) [line 54]\n REMOVE_TEMPS(n$3); [line 54]\n " shape="box"] + 48 -> 44 ; +47 [label="47: Prune (false branch) \n n$0=*&x:class X * [line 53]\n PRUNE((n$0 == 0), false); [line 53]\n REMOVE_TEMPS(n$0); [line 53]\n " shape="invhouse"] - 47 -> 46 ; -46 [label="46: Return Stmt \n n$1=*&x:class X * [line 55]\n n$2=_fun_X_div(n$1:class X ) [line 55]\n *&return:int =n$2 [line 55]\n REMOVE_TEMPS(n$1,n$2); [line 55]\n NULLIFY(&x,false); [line 55]\n APPLY_ABSTRACTION; [line 55]\n " shape="box"] + 47 -> 45 ; +46 [label="46: Prune (true branch) \n n$0=*&x:class X * [line 53]\n PRUNE((n$0 != 0), true); [line 53]\n REMOVE_TEMPS(n$0); [line 53]\n " shape="invhouse"] - 46 -> 42 ; -45 [label="45: Prune (false branch) \n n$0=*&x:class X * [line 53]\n PRUNE((n$0 == 0), false); [line 53]\n REMOVE_TEMPS(n$0); [line 53]\n " shape="invhouse"] + 46 -> 49 ; +45 [label="45: + \n NULLIFY(&x,false); [line 53]\n " ] - 45 -> 43 ; -44 [label="44: Prune (true branch) \n n$0=*&x:class X * [line 53]\n PRUNE((n$0 != 0), true); [line 53]\n REMOVE_TEMPS(n$0); [line 53]\n " shape="invhouse"] + 45 -> 44 ; +44 [label="44: Exit method_div1_ptr \n " color=yellow style=filled] - 44 -> 47 ; -43 [label="43: + \n NULLIFY(&x,false); [line 53]\n " ] +43 [label="43: Start method_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 52]\n " color=yellow style=filled] - 43 -> 42 ; -42 [label="42: Exit method_div1_ptr \n " color=yellow style=filled] + 43 -> 46 ; + 43 -> 47 ; +42 [label="42: Call _fun_zero_ptr \n n$3=*&x:class X * [line 47]\n _fun_zero_ptr(n$3:class X *) [line 47]\n REMOVE_TEMPS(n$3); [line 47]\n " shape="box"] -41 [label="41: Start method_div1_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 52]\n " color=yellow style=filled] + 42 -> 41 ; +41 [label="41: Return Stmt \n n$1=*&x:class X * [line 48]\n n$2=_fun_X_div(n$1:class X ) [line 48]\n *&return:int =n$2 [line 48]\n REMOVE_TEMPS(n$1,n$2); [line 48]\n NULLIFY(&x,false); [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] - 41 -> 44 ; - 41 -> 45 ; -40 [label="40: Call _fun_zero_ptr \n n$3=*&x:class X * [line 47]\n _fun_zero_ptr(n$3:class X *) [line 47]\n REMOVE_TEMPS(n$3); [line 47]\n " shape="box"] + 41 -> 37 ; +40 [label="40: Prune (false branch) \n n$0=*&x:class X * [line 46]\n PRUNE((n$0 == 0), false); [line 46]\n REMOVE_TEMPS(n$0); [line 46]\n " shape="invhouse"] - 40 -> 39 ; -39 [label="39: Return Stmt \n n$1=*&x:class X * [line 48]\n n$2=_fun_X_div(n$1:class X ) [line 48]\n *&return:int =n$2 [line 48]\n REMOVE_TEMPS(n$1,n$2); [line 48]\n NULLIFY(&x,false); [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] + 40 -> 38 ; +39 [label="39: Prune (true branch) \n n$0=*&x:class X * [line 46]\n PRUNE((n$0 != 0), true); [line 46]\n REMOVE_TEMPS(n$0); [line 46]\n " shape="invhouse"] - 39 -> 35 ; -38 [label="38: Prune (false branch) \n n$0=*&x:class X * [line 46]\n PRUNE((n$0 == 0), false); [line 46]\n REMOVE_TEMPS(n$0); [line 46]\n " shape="invhouse"] + 39 -> 42 ; +38 [label="38: + \n NULLIFY(&x,false); [line 46]\n " ] - 38 -> 36 ; -37 [label="37: Prune (true branch) \n n$0=*&x:class X * [line 46]\n PRUNE((n$0 != 0), true); [line 46]\n REMOVE_TEMPS(n$0); [line 46]\n " shape="invhouse"] + 38 -> 37 ; +37 [label="37: Exit method_div0_ptr \n " color=yellow style=filled] - 37 -> 40 ; -36 [label="36: + \n NULLIFY(&x,false); [line 46]\n " ] +36 [label="36: Start method_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 45]\n " color=yellow style=filled] - 36 -> 35 ; -35 [label="35: Exit method_div0_ptr \n " color=yellow style=filled] + 36 -> 39 ; + 36 -> 40 ; +35 [label="35: Return Stmt \n *&return:class X &=&#GB$global [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] -34 [label="34: Start method_div0_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 45]\n " color=yellow style=filled] + 35 -> 34 ; +34 [label="34: Exit get_global_ref \n " color=yellow style=filled] - 34 -> 37 ; - 34 -> 38 ; -33 [label="33: Return Stmt \n *&return:class X &=&#GB$global [line 43]\n APPLY_ABSTRACTION; [line 43]\n " shape="box"] +33 [label="33: Start get_global_ref\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 43]\n " color=yellow style=filled] - 33 -> 32 ; -32 [label="32: Exit get_global_ref \n " color=yellow style=filled] + 33 -> 35 ; +32 [label="32: Return Stmt \n *&return:class X *=&#GB$global [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"] -31 [label="31: Start get_global_ref\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 43]\n " color=yellow style=filled] + 32 -> 31 ; +31 [label="31: Exit get_global_ptr \n " color=yellow style=filled] - 31 -> 33 ; -30 [label="30: Return Stmt \n *&return:class X *=&#GB$global [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"] +30 [label="30: Start get_global_ptr\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 42]\n " color=yellow style=filled] - 30 -> 29 ; -29 [label="29: Exit get_global_ptr \n " color=yellow style=filled] + 30 -> 32 ; +29 [label="29: BinaryOperatorStmt: Assign \n n$0=*&x:class X & [line 38]\n n$1=*&val:int [line 38]\n *n$0.f:int =n$1 [line 38]\n REMOVE_TEMPS(n$0,n$1); [line 38]\n NULLIFY(&val,false); [line 38]\n NULLIFY(&x,false); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"] -28 [label="28: Start get_global_ptr\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 42]\n " color=yellow style=filled] + 29 -> 28 ; +28 [label="28: Exit set_field_ref \n " color=yellow style=filled] - 28 -> 30 ; -27 [label="27: BinaryOperatorStmt: Assign \n n$0=*&x:class X & [line 38]\n n$1=*&val:int [line 38]\n *n$0.f:int =n$1 [line 38]\n REMOVE_TEMPS(n$0,n$1); [line 38]\n NULLIFY(&val,false); [line 38]\n NULLIFY(&x,false); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"] +27 [label="27: Start set_field_ref\nFormals: x:class X & val:int \nLocals: \n DECLARE_LOCALS(&return); [line 37]\n " color=yellow style=filled] - 27 -> 26 ; -26 [label="26: Exit set_field_ref \n " color=yellow style=filled] + 27 -> 29 ; +26 [label="26: Call _fun_X_nonzero \n n$0=*&x:class X & [line 34]\n _fun_X_nonzero(n$0:class X ) [line 34]\n REMOVE_TEMPS(n$0); [line 34]\n NULLIFY(&x,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] -25 [label="25: Start set_field_ref\nFormals: x:class X & val:int \nLocals: \n DECLARE_LOCALS(&return); [line 37]\n " color=yellow style=filled] + 26 -> 25 ; +25 [label="25: Exit nonzero_ref \n " color=yellow style=filled] - 25 -> 27 ; -24 [label="24: Call _fun_X_nonzero \n n$0=*&x:class X & [line 34]\n _fun_X_nonzero(n$0:class X ) [line 34]\n REMOVE_TEMPS(n$0); [line 34]\n NULLIFY(&x,false); [line 34]\n APPLY_ABSTRACTION; [line 34]\n " shape="box"] +24 [label="24: Start nonzero_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] - 24 -> 23 ; -23 [label="23: Exit nonzero_ref \n " color=yellow style=filled] + 24 -> 26 ; +23 [label="23: Call _fun_X_zero \n n$0=*&x:class X & [line 30]\n _fun_X_zero(n$0:class X ) [line 30]\n REMOVE_TEMPS(n$0); [line 30]\n NULLIFY(&x,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] -22 [label="22: Start nonzero_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] + 23 -> 22 ; +22 [label="22: Exit zero_ref \n " color=yellow style=filled] - 22 -> 24 ; -21 [label="21: Call _fun_X_zero \n n$0=*&x:class X & [line 30]\n _fun_X_zero(n$0:class X ) [line 30]\n REMOVE_TEMPS(n$0); [line 30]\n NULLIFY(&x,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] +21 [label="21: Start zero_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] - 21 -> 20 ; -20 [label="20: Exit zero_ref \n " color=yellow style=filled] + 21 -> 23 ; +20 [label="20: BinaryOperatorStmt: Assign \n n$0=*&x:class X * [line 26]\n n$1=*&val:int [line 26]\n *n$0.f:int =n$1 [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&val,false); [line 26]\n NULLIFY(&x,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] -19 [label="19: Start zero_ref\nFormals: x:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] + 20 -> 19 ; +19 [label="19: Exit set_field_ptr \n " color=yellow style=filled] - 19 -> 21 ; -18 [label="18: BinaryOperatorStmt: Assign \n n$0=*&x:class X * [line 26]\n n$1=*&val:int [line 26]\n *n$0.f:int =n$1 [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&val,false); [line 26]\n NULLIFY(&x,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] +18 [label="18: Start set_field_ptr\nFormals: x:class X * val:int \nLocals: \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] - 18 -> 17 ; -17 [label="17: Exit set_field_ptr \n " color=yellow style=filled] + 18 -> 20 ; +17 [label="17: Call _fun_X_nonzero \n n$0=*&x:class X * [line 22]\n _fun_X_nonzero(n$0:class X ) [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n NULLIFY(&x,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] -16 [label="16: Start set_field_ptr\nFormals: x:class X * val:int \nLocals: \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] + 17 -> 16 ; +16 [label="16: Exit nonzero_ptr \n " color=yellow style=filled] - 16 -> 18 ; -15 [label="15: Call _fun_X_nonzero \n n$0=*&x:class X * [line 22]\n _fun_X_nonzero(n$0:class X ) [line 22]\n REMOVE_TEMPS(n$0); [line 22]\n NULLIFY(&x,false); [line 22]\n APPLY_ABSTRACTION; [line 22]\n " shape="box"] +15 [label="15: Start nonzero_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled] - 15 -> 14 ; -14 [label="14: Exit nonzero_ptr \n " color=yellow style=filled] + 15 -> 17 ; +14 [label="14: Call _fun_X_zero \n n$0=*&x:class X * [line 18]\n _fun_X_zero(n$0:class X ) [line 18]\n REMOVE_TEMPS(n$0); [line 18]\n NULLIFY(&x,false); [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"] -13 [label="13: Start nonzero_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 21]\n " color=yellow style=filled] + 14 -> 13 ; +13 [label="13: Exit zero_ptr \n " color=yellow style=filled] - 13 -> 15 ; -12 [label="12: Call _fun_X_zero \n n$0=*&x:class X * [line 18]\n _fun_X_zero(n$0:class X ) [line 18]\n REMOVE_TEMPS(n$0); [line 18]\n NULLIFY(&x,false); [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"] +12 [label="12: Start zero_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled] - 12 -> 11 ; -11 [label="11: Exit zero_ptr \n " color=yellow style=filled] + 12 -> 14 ; +11 [label="11: Exit X_X \n " color=yellow style=filled] -10 [label="10: Start zero_ptr\nFormals: x:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 17]\n " color=yellow style=filled] +10 [label="10: Start X_X\nFormals: this:class X *\nLocals: \n DECLARE_LOCALS(&return); [line 10]\n NULLIFY(&this,false); [line 10]\n " color=yellow style=filled] - 10 -> 12 ; + 10 -> 11 ; 9 [label="9: Return Stmt \n n$0=*&this:class X * [line 14]\n n$1=*n$0.f:int [line 14]\n *&return:int =(1 / n$1) [line 14]\n REMOVE_TEMPS(n$0,n$1); [line 14]\n NULLIFY(&this,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] diff --git a/infer/tests/codetoanalyze/cpp/frontend/types/inheritance.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/types/inheritance.cpp.dot index 6a1ff3f9f..87c30c53d 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/types/inheritance.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/types/inheritance.cpp.dot @@ -1,58 +1,72 @@ digraph iCFG { -20 [label="20: DeclStmt \n n$14=_fun___new(sizeof(class Base ):unsigned long ) [line 22]\n *&b:class Base *=n$14 [line 22]\n REMOVE_TEMPS(n$14); [line 22]\n " shape="box"] +24 [label="24: DeclStmt \n n$14=_fun___new(sizeof(class Base ):unsigned long ) [line 22]\n *&b:class Base *=n$14 [line 22]\n REMOVE_TEMPS(n$14); [line 22]\n " shape="box"] + + + 24 -> 23 ; +23 [label="23: DeclStmt \n n$13=_fun___new(sizeof(class Sub ):unsigned long ) [line 23]\n *&s1:class Base *=n$13 [line 23]\n REMOVE_TEMPS(n$13); [line 23]\n " shape="box"] + + + 23 -> 22 ; +22 [label="22: DeclStmt \n n$12=_fun___new(sizeof(class Sub ):unsigned long ) [line 24]\n *&s2:class Sub *=n$12 [line 24]\n REMOVE_TEMPS(n$12); [line 24]\n " shape="box"] + + + 22 -> 21 ; +21 [label="21: Call _fun_Base_fun \n n$10=*&b:class Base * [line 26]\n n$11=_fun_Base_fun(n$10:class Base ) [line 26]\n REMOVE_TEMPS(n$10,n$11); [line 26]\n " shape="box"] + + + 21 -> 20 ; +20 [label="20: Call _fun_Base_fun \n n$8=*&s1:class Base * [line 27]\n n$9=_fun_Base_fun(n$8:class Base ) [line 27]\n REMOVE_TEMPS(n$8,n$9); [line 27]\n " shape="box"] 20 -> 19 ; -19 [label="19: DeclStmt \n n$13=_fun___new(sizeof(class Sub ):unsigned long ) [line 23]\n *&s1:class Base *=n$13 [line 23]\n REMOVE_TEMPS(n$13); [line 23]\n " shape="box"] +19 [label="19: Call _fun_Base_fun \n n$6=*&s2:class Sub * [line 28]\n n$7=_fun_Base_fun(n$6:class Base ) [line 28]\n REMOVE_TEMPS(n$6,n$7); [line 28]\n " shape="box"] 19 -> 18 ; -18 [label="18: DeclStmt \n n$12=_fun___new(sizeof(class Sub ):unsigned long ) [line 24]\n *&s2:class Sub *=n$12 [line 24]\n REMOVE_TEMPS(n$12); [line 24]\n " shape="box"] +18 [label="18: Call _fun_Base_fun_redefine \n n$4=*&b:class Base * [line 30]\n n$5=_fun_Base_fun_redefine(n$4:class Base ) [line 30]\n REMOVE_TEMPS(n$4,n$5); [line 30]\n NULLIFY(&b,false); [line 30]\n " shape="box"] 18 -> 17 ; -17 [label="17: Call _fun_Base_fun \n n$10=*&b:class Base * [line 26]\n n$11=_fun_Base_fun(n$10:class Base ) [line 26]\n REMOVE_TEMPS(n$10,n$11); [line 26]\n " shape="box"] +17 [label="17: Call _fun_Base_fun_redefine \n n$2=*&s1:class Base * [line 31]\n n$3=_fun_Base_fun_redefine(n$2:class Base ) [line 31]\n REMOVE_TEMPS(n$2,n$3); [line 31]\n NULLIFY(&s1,false); [line 31]\n " shape="box"] 17 -> 16 ; -16 [label="16: Call _fun_Base_fun \n n$8=*&s1:class Base * [line 27]\n n$9=_fun_Base_fun(n$8:class Base ) [line 27]\n REMOVE_TEMPS(n$8,n$9); [line 27]\n " shape="box"] +16 [label="16: Call _fun_Sub_fun_redefine \n n$0=*&s2:class Sub * [line 32]\n n$1=_fun_Sub_fun_redefine(n$0:class Sub ) [line 32]\n REMOVE_TEMPS(n$0,n$1); [line 32]\n NULLIFY(&s2,false); [line 32]\n APPLY_ABSTRACTION; [line 32]\n " shape="box"] 16 -> 15 ; -15 [label="15: Call _fun_Base_fun \n n$6=*&s2:class Sub * [line 28]\n n$7=_fun_Base_fun(n$6:class Base ) [line 28]\n REMOVE_TEMPS(n$6,n$7); [line 28]\n " shape="box"] +15 [label="15: Exit call_static_methods \n " color=yellow style=filled] - 15 -> 14 ; -14 [label="14: Call _fun_Base_fun_redefine \n n$4=*&b:class Base * [line 30]\n n$5=_fun_Base_fun_redefine(n$4:class Base ) [line 30]\n REMOVE_TEMPS(n$4,n$5); [line 30]\n NULLIFY(&b,false); [line 30]\n " shape="box"] +14 [label="14: Start call_static_methods\nFormals: \nLocals: s2:class Sub * s1:class Base * b:class Base * \n DECLARE_LOCALS(&return,&s2,&s1,&b); [line 21]\n NULLIFY(&b,false); [line 21]\n NULLIFY(&s1,false); [line 21]\n NULLIFY(&s2,false); [line 21]\n " color=yellow style=filled] - 14 -> 13 ; -13 [label="13: Call _fun_Base_fun_redefine \n n$2=*&s1:class Base * [line 31]\n n$3=_fun_Base_fun_redefine(n$2:class Base ) [line 31]\n REMOVE_TEMPS(n$2,n$3); [line 31]\n NULLIFY(&s1,false); [line 31]\n " shape="box"] + 14 -> 24 ; +13 [label="13: Exit Sub_Sub \n " color=yellow style=filled] - 13 -> 12 ; -12 [label="12: Call _fun_Sub_fun_redefine \n n$0=*&s2:class Sub * [line 32]\n n$1=_fun_Sub_fun_redefine(n$0:class Sub ) [line 32]\n REMOVE_TEMPS(n$0,n$1); [line 32]\n NULLIFY(&s2,false); [line 32]\n APPLY_ABSTRACTION; [line 32]\n " shape="box"] +12 [label="12: Start Sub_Sub\nFormals: this:class Sub *\nLocals: \n DECLARE_LOCALS(&return); [line 16]\n NULLIFY(&this,false); [line 16]\n " color=yellow style=filled] - 12 -> 11 ; -11 [label="11: Exit call_static_methods \n " color=yellow style=filled] + 12 -> 13 ; +11 [label="11: Return Stmt \n *&return:int =20 [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"] -10 [label="10: Start call_static_methods\nFormals: \nLocals: s2:class Sub * s1:class Base * b:class Base * \n DECLARE_LOCALS(&return,&s2,&s1,&b); [line 21]\n NULLIFY(&b,false); [line 21]\n NULLIFY(&s1,false); [line 21]\n NULLIFY(&s2,false); [line 21]\n " color=yellow style=filled] + 11 -> 10 ; +10 [label="10: Exit Sub_fun_redefine \n " color=yellow style=filled] - 10 -> 20 ; -9 [label="9: Return Stmt \n *&return:int =20 [line 18]\n APPLY_ABSTRACTION; [line 18]\n " shape="box"] +9 [label="9: Start Sub_fun_redefine\nFormals: this:class Sub *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n NULLIFY(&this,false); [line 18]\n " color=yellow style=filled] - 9 -> 8 ; -8 [label="8: Exit Sub_fun_redefine \n " color=yellow style=filled] + 9 -> 11 ; +8 [label="8: Exit Base_Base \n " color=yellow style=filled] -7 [label="7: Start Sub_fun_redefine\nFormals: this:class Sub *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n NULLIFY(&this,false); [line 18]\n " color=yellow style=filled] +7 [label="7: Start Base_Base\nFormals: this:class Base *\nLocals: \n DECLARE_LOCALS(&return); [line 10]\n NULLIFY(&this,false); [line 10]\n " color=yellow style=filled] - 7 -> 9 ; + 7 -> 8 ; 6 [label="6: Return Stmt \n *&return:int =10 [line 13]\n APPLY_ABSTRACTION; [line 13]\n " shape="box"] diff --git a/infer/tests/frontend/cpp/ConstructorsTest.java b/infer/tests/frontend/cpp/ConstructorsTest.java new file mode 100644 index 000000000..6e38ac962 --- /dev/null +++ b/infer/tests/frontend/cpp/ConstructorsTest.java @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2013 - 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. +*/ + +package frontend.cpp; + +import org.junit.Rule; +import org.junit.Test; + +import java.io.IOException; + +import utils.DebuggableTemporaryFolder; +import utils.InferException; +import utils.ClangFrontendUtils; + +public class ConstructorsTest { + + String basePath = "infer/tests/codetoanalyze/cpp/frontend/constructors/"; + + @Rule + public DebuggableTemporaryFolder folder = new DebuggableTemporaryFolder(); + + void frontendTest(String fileRelative) throws InterruptedException, IOException, InferException { + ClangFrontendUtils.createAndCompareCppDotFiles(folder, basePath + fileRelative); + } + + @Test + public void testInlineMethodDotFilesMatch() + throws InterruptedException, IOException, InferException { + frontendTest("constructor_with_body.cpp"); + } + +} diff --git a/infer/tests/frontend/cpp/NestedOperatorsTest.java b/infer/tests/frontend/cpp/NestedOperatorsTest.java index 60767b7f8..71fdb69df 100644 --- a/infer/tests/frontend/cpp/NestedOperatorsTest.java +++ b/infer/tests/frontend/cpp/NestedOperatorsTest.java @@ -42,7 +42,9 @@ public class NestedOperatorsTest { @Test public void whenCaptureRunUnionThenDotFilesAreTheSame() throws InterruptedException, IOException, InferException { - frontendTest("union.c"); + // .dot file for cpp is different due to autogenerated constructors for union type + // otherwise cfgs should look the same for C and C++ + frontendTest("union.cpp"); } @Test