From da3a106541555c2c8a45d971178d82fe161ec7c4 Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Wed, 3 Feb 2016 08:08:45 -0800 Subject: [PATCH] Always translate CXXRecordDecl as Sil.Class Summary: public It turns out that C-like structs in C++ may have methods generated by clang (constructors for example). If struct has a method, it needs to have Sil.Class type - make all CXXRecordDecls Sil.Class types by default. Reviewed By: cristianoc Differential Revision: D2895567 fb-gh-sync-id: 8eb18c3 --- infer/src/clang/cTypes_decl.ml | 15 +++++++-------- .../c/frontend/nestedoperators/union.cpp.dot | 4 ++-- .../cpp/frontend/methods/return_struct.cpp.dot | 10 +++++----- .../cpp/frontend/namespace/namespace.cpp.dot | 4 ++-- .../cpp/frontend/templates/simple.cpp.dot | 12 ++++++------ .../cpp/frontend/types/inheritance_field.cpp.dot | 12 ++++++------ .../cpp/frontend/types/struct.cpp.dot | 6 +++--- 7 files changed, 31 insertions(+), 32 deletions(-) diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index a727ce1e5..d7c3e09d5 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -98,18 +98,17 @@ let create_csu opt_type = (* We need to take the name out of the type as the struct can be anonymous*) let get_record_name_csu decl = let open Clang_ast_t in - let name_info, opt_type, should_be_class = match decl with - | RecordDecl (_, name_info, opt_type, _, _, _, _) -> name_info, opt_type, false - | CXXRecordDecl (_, name_info, opt_type, _, _, _, _, cxx_record_info) - | ClassTemplateSpecializationDecl (_, name_info, opt_type, _, _, _, _, cxx_record_info) -> + let name_info, csu = match decl with + | RecordDecl (_, name_info, opt_type, _, _, _, _) -> + name_info, create_csu opt_type + | CXXRecordDecl (_, name_info, opt_type, _, _, _, _, _) + | ClassTemplateSpecializationDecl (_, name_info, opt_type, _, _, _, _, _) -> (* we use Csu.Class for C++ because we expect Csu.Class csu from *) (* types that have methods. And in C++ struct/class/union can have methods *) - name_info, opt_type, not cxx_record_info.xrdi_is_c_like + name_info, Csu.Class Csu.CPP | _-> assert false in - let csu = create_csu opt_type in - let csu' = if should_be_class then Csu.Class Csu.CPP else csu in let name = Ast_utils.get_qualified_name name_info in - csu', name + csu, name let get_record_name decl = snd (get_record_name_csu decl) diff --git a/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot b/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot index 2a72b25dc..07c5d995d 100644 --- a/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot +++ b/infer/tests/codetoanalyze/c/frontend/nestedoperators/union.cpp.dot @@ -1,5 +1,5 @@ digraph iCFG { -9 [label="9: BinaryOperatorStmt: Assign \n n$3=*&#GB$x:struct (anonymous struct 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 [label="9: BinaryOperatorStmt: Assign \n n$3=*&#GB$x:class (anonymous struct 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 ; @@ -11,7 +11,7 @@ digraph iCFG { 7 -> 6 ; -6 [label="6: BinaryOperatorStmt: Assign \n n$0=*&#GB$x:struct (anonymous struct 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 [label="6: BinaryOperatorStmt: Assign \n n$0=*&#GB$x:class (anonymous struct 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 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/methods/return_struct.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/methods/return_struct.cpp.dot index 2657b2081..c25cd9aba 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/methods/return_struct.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/methods/return_struct.cpp.dot @@ -1,5 +1,5 @@ digraph iCFG { -12 [label="12: DeclStmt \n n$2=*&a:class A * [line 22]\n _fun_A_get(n$2:class A *,1:int ,&SIL_materialize_temp__n$1:struct X *) [line 22]\n _fun_X_X(&x:struct X *,&SIL_materialize_temp__n$1:struct X ) [line 22]\n REMOVE_TEMPS(n$2); [line 22]\n NULLIFY(&a,false); [line 22]\n " shape="box"] +12 [label="12: DeclStmt \n n$2=*&a:class A * [line 22]\n _fun_A_get(n$2:class A *,1:int ,&SIL_materialize_temp__n$1:class X *) [line 22]\n _fun_X_X(&x:class X *,&SIL_materialize_temp__n$1:class X ) [line 22]\n REMOVE_TEMPS(n$2); [line 22]\n NULLIFY(&a,false); [line 22]\n " shape="box"] 12 -> 11 ; @@ -10,22 +10,22 @@ digraph iCFG { 10 [label="10: Exit test \n " color=yellow style=filled] -9 [label="9: Start test\nFormals: a:class A *\nLocals: x:struct X SIL_materialize_temp__n$1:struct X \n DECLARE_LOCALS(&return,&x,&SIL_materialize_temp__n$1); [line 21]\n " color=yellow style=filled] +9 [label="9: Start test\nFormals: a:class A *\nLocals: x:class X SIL_materialize_temp__n$1:class X \n DECLARE_LOCALS(&return,&x,&SIL_materialize_temp__n$1); [line 21]\n " color=yellow style=filled] 9 -> 12 ; -8 [label="8: DeclStmt \n _fun_X_X(&x:struct X *) [line 16]\n " shape="box"] +8 [label="8: DeclStmt \n _fun_X_X(&x:class X *) [line 16]\n " shape="box"] 8 -> 7 ; -7 [label="7: Return Stmt \n n$0=*&__return_param:void * [line 17]\n _fun_X_X(n$0:struct X *,&x:struct X ) [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n NULLIFY(&__return_param,false); [line 17]\n NULLIFY(&x,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] +7 [label="7: Return Stmt \n n$0=*&__return_param:void * [line 17]\n _fun_X_X(n$0:class X *,&x:class X ) [line 17]\n REMOVE_TEMPS(n$0); [line 17]\n NULLIFY(&__return_param,false); [line 17]\n NULLIFY(&x,false); [line 17]\n APPLY_ABSTRACTION; [line 17]\n " shape="box"] 7 -> 6 ; 6 [label="6: Exit A_get \n " color=yellow style=filled] -5 [label="5: Start A_get\nFormals: this:class A * p:int __return_param:struct X *\nLocals: x:struct X \n DECLARE_LOCALS(&return,&x); [line 15]\n NULLIFY(&p,false); [line 15]\n NULLIFY(&this,false); [line 15]\n " color=yellow style=filled] +5 [label="5: Start A_get\nFormals: this:class A * p:int __return_param:class X *\nLocals: x:class X \n DECLARE_LOCALS(&return,&x); [line 15]\n NULLIFY(&p,false); [line 15]\n NULLIFY(&this,false); [line 15]\n " color=yellow style=filled] 5 -> 8 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot index 6c4a5b6f1..89a6173b2 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/namespace/namespace.cpp.dot @@ -1,5 +1,5 @@ digraph iCFG { -24 [label="24: DeclStmt \n _fun_foo::my_record_(&x:struct foo::my_record *) [line 45]\n " shape="box"] +24 [label="24: DeclStmt \n _fun_foo::my_record_(&x:class foo::my_record *) [line 45]\n " shape="box"] 24 -> 23 ; @@ -42,7 +42,7 @@ digraph iCFG { 14 [label="14: Exit main \n " color=yellow style=filled] -13 [label="13: Start main\nFormals: \nLocals: rect2:class foo::Rectangle rect1:class bar::Rectangle x:struct foo::my_record j:double i:int \n DECLARE_LOCALS(&return,&rect2,&rect1,&x,&j,&i); [line 40]\n NULLIFY(&i,false); [line 40]\n NULLIFY(&j,false); [line 40]\n " color=yellow style=filled] +13 [label="13: Start main\nFormals: \nLocals: rect2:class foo::Rectangle rect1:class bar::Rectangle x:class foo::my_record j:double i:int \n DECLARE_LOCALS(&return,&rect2,&rect1,&x,&j,&i); [line 40]\n NULLIFY(&i,false); [line 40]\n NULLIFY(&j,false); [line 40]\n " color=yellow style=filled] 13 -> 24 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/templates/simple.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/templates/simple.cpp.dot index c2df8bc21..c05d7d5fc 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/templates/simple.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/templates/simple.cpp.dot @@ -1,31 +1,31 @@ digraph iCFG { -8 [label="8: BinaryOperatorStmt: Assign \n n$2=*&v:struct X & [line 25]\n *n$2.field:int =0 [line 25]\n REMOVE_TEMPS(n$2); [line 25]\n " shape="box"] +8 [label="8: BinaryOperatorStmt: Assign \n n$2=*&v:class X & [line 25]\n *n$2.field:int =0 [line 25]\n REMOVE_TEMPS(n$2); [line 25]\n " shape="box"] 8 -> 7 ; -7 [label="7: Return Stmt \n n$0=*&v:struct X & [line 26]\n n$1=*n$0.field:int [line 26]\n *&return:int =(1 / n$1) [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&v,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] +7 [label="7: Return Stmt \n n$0=*&v:class X & [line 26]\n n$1=*n$0.field:int [line 26]\n *&return:int =(1 / n$1) [line 26]\n REMOVE_TEMPS(n$0,n$1); [line 26]\n NULLIFY(&v,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] 7 -> 6 ; 6 [label="6: Exit div0_struct_field \n " color=yellow style=filled] -5 [label="5: Start div0_struct_field\nFormals: v:struct X &\nLocals: \n DECLARE_LOCALS(&return); [line 24]\n " color=yellow style=filled] +5 [label="5: Start div0_struct_field\nFormals: v:class X &\nLocals: \n DECLARE_LOCALS(&return); [line 24]\n " color=yellow style=filled] 5 -> 8 ; -4 [label="4: BinaryOperatorStmt: Assign \n n$2=*&v:struct Container & [line 20]\n *n$2.field:int =0 [line 20]\n REMOVE_TEMPS(n$2); [line 20]\n " shape="box"] +4 [label="4: BinaryOperatorStmt: Assign \n n$2=*&v:class Container & [line 20]\n *n$2.field:int =0 [line 20]\n REMOVE_TEMPS(n$2); [line 20]\n " shape="box"] 4 -> 3 ; -3 [label="3: Return Stmt \n n$0=*&v:struct Container & [line 21]\n n$1=*n$0.field:int [line 21]\n *&return:int =(1 / n$1) [line 21]\n REMOVE_TEMPS(n$0,n$1); [line 21]\n NULLIFY(&v,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] +3 [label="3: Return Stmt \n n$0=*&v:class Container & [line 21]\n n$1=*n$0.field:int [line 21]\n *&return:int =(1 / n$1) [line 21]\n REMOVE_TEMPS(n$0,n$1); [line 21]\n NULLIFY(&v,false); [line 21]\n APPLY_ABSTRACTION; [line 21]\n " shape="box"] 3 -> 2 ; 2 [label="2: Exit div0_template_field \n " color=yellow style=filled] -1 [label="1: Start div0_template_field\nFormals: v:struct Container &\nLocals: \n DECLARE_LOCALS(&return); [line 19]\n " color=yellow style=filled] +1 [label="1: Start div0_template_field\nFormals: v:class Container &\nLocals: \n DECLARE_LOCALS(&return); [line 19]\n " color=yellow style=filled] 1 -> 4 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/types/inheritance_field.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/types/inheritance_field.cpp.dot index 1c839e857..f732e1ae0 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/types/inheritance_field.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/types/inheritance_field.cpp.dot @@ -7,14 +7,14 @@ digraph iCFG { 40 -> 39 ; -39 [label="39: Return Stmt \n n$0=*&b:struct Base1 * [line 69]\n n$1=*n$0.b1:int [line 69]\n *&return:int =(1 / n$1) [line 69]\n REMOVE_TEMPS(n$0,n$1); [line 69]\n NULLIFY(&b,false); [line 69]\n APPLY_ABSTRACTION; [line 69]\n " shape="box"] +39 [label="39: Return Stmt \n n$0=*&b:class Base1 * [line 69]\n n$1=*n$0.b1:int [line 69]\n *&return:int =(1 / n$1) [line 69]\n REMOVE_TEMPS(n$0,n$1); [line 69]\n NULLIFY(&b,false); [line 69]\n APPLY_ABSTRACTION; [line 69]\n " shape="box"] 39 -> 38 ; 38 [label="38: Exit div1_cast \n " color=yellow style=filled] -37 [label="37: Start div1_cast\nFormals: s:class Sub *\nLocals: b:struct Base1 * \n DECLARE_LOCALS(&return,&b); [line 66]\n NULLIFY(&b,false); [line 66]\n " color=yellow style=filled] +37 [label="37: Start div1_cast\nFormals: s:class Sub *\nLocals: b:class Base1 * \n DECLARE_LOCALS(&return,&b); [line 66]\n NULLIFY(&b,false); [line 66]\n " color=yellow style=filled] 37 -> 41 ; @@ -79,14 +79,14 @@ digraph iCFG { 21 -> 20 ; -20 [label="20: Return Stmt \n n$0=*&b:struct Base1 & [line 46]\n n$1=*n$0.b1:int [line 46]\n *&return:int =(1 / n$1) [line 46]\n REMOVE_TEMPS(n$0,n$1); [line 46]\n NULLIFY(&b,false); [line 46]\n NULLIFY(&s,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] +20 [label="20: Return Stmt \n n$0=*&b:class Base1 & [line 46]\n n$1=*n$0.b1:int [line 46]\n *&return:int =(1 / n$1) [line 46]\n REMOVE_TEMPS(n$0,n$1); [line 46]\n NULLIFY(&b,false); [line 46]\n NULLIFY(&s,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] 20 -> 19 ; 19 [label="19: Exit div0_cast_ref \n " color=yellow style=filled] -18 [label="18: Start div0_cast_ref\nFormals: s:class Sub \nLocals: b:struct Base1 & \n DECLARE_LOCALS(&return,&b); [line 43]\n NULLIFY(&b,false); [line 43]\n " color=yellow style=filled] +18 [label="18: Start div0_cast_ref\nFormals: s:class Sub \nLocals: b:class Base1 & \n DECLARE_LOCALS(&return,&b); [line 43]\n NULLIFY(&b,false); [line 43]\n " color=yellow style=filled] 18 -> 22 ; @@ -98,14 +98,14 @@ digraph iCFG { 16 -> 15 ; -15 [label="15: Return Stmt \n n$0=*&b:struct Base1 * [line 40]\n n$1=*n$0.b1:int [line 40]\n *&return:int =(1 / n$1) [line 40]\n REMOVE_TEMPS(n$0,n$1); [line 40]\n NULLIFY(&b,false); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"] +15 [label="15: Return Stmt \n n$0=*&b:class Base1 * [line 40]\n n$1=*n$0.b1:int [line 40]\n *&return:int =(1 / n$1) [line 40]\n REMOVE_TEMPS(n$0,n$1); [line 40]\n NULLIFY(&b,false); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"] 15 -> 14 ; 14 [label="14: Exit div0_cast \n " color=yellow style=filled] -13 [label="13: Start div0_cast\nFormals: s:class Sub *\nLocals: b:struct Base1 * \n DECLARE_LOCALS(&return,&b); [line 37]\n NULLIFY(&b,false); [line 37]\n " color=yellow style=filled] +13 [label="13: Start div0_cast\nFormals: s:class Sub *\nLocals: b:class Base1 * \n DECLARE_LOCALS(&return,&b); [line 37]\n NULLIFY(&b,false); [line 37]\n " color=yellow style=filled] 13 -> 17 ; diff --git a/infer/tests/codetoanalyze/cpp/frontend/types/struct.cpp.dot b/infer/tests/codetoanalyze/cpp/frontend/types/struct.cpp.dot index e0c81eda7..e64accf18 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/types/struct.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/frontend/types/struct.cpp.dot @@ -1,9 +1,9 @@ digraph iCFG { -6 [label="6: BinaryOperatorStmt: Assign \n n$3=*&xs:struct X_struct * [line 24]\n *n$3.a:int =10 [line 24]\n REMOVE_TEMPS(n$3); [line 24]\n " shape="box"] +6 [label="6: BinaryOperatorStmt: Assign \n n$3=*&xs:class X_struct * [line 24]\n *n$3.a:int =10 [line 24]\n REMOVE_TEMPS(n$3); [line 24]\n " shape="box"] 6 -> 5 ; -5 [label="5: BinaryOperatorStmt: Assign \n n$2=*&xs:struct X_struct * [line 25]\n *n$2.b:int =20 [line 25]\n REMOVE_TEMPS(n$2); [line 25]\n NULLIFY(&xs,false); [line 25]\n " shape="box"] +5 [label="5: BinaryOperatorStmt: Assign \n n$2=*&xs:class X_struct * [line 25]\n *n$2.b:int =20 [line 25]\n REMOVE_TEMPS(n$2); [line 25]\n NULLIFY(&xs,false); [line 25]\n " shape="box"] 5 -> 4 ; @@ -18,7 +18,7 @@ digraph iCFG { 2 [label="2: Exit test \n " color=yellow style=filled] -1 [label="1: Start test\nFormals: \nLocals: xc:class X_class * xs:struct X_struct * \n DECLARE_LOCALS(&return,&xc,&xs); [line 21]\n " color=yellow style=filled] +1 [label="1: Start test\nFormals: \nLocals: xc:class X_class * xs:class X_struct * \n DECLARE_LOCALS(&return,&xc,&xs); [line 21]\n " color=yellow style=filled] 1 -> 6 ;