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