From 2365e6244dee838b8823037b0843618bd69aaf32 Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Wed, 8 Jul 2015 13:45:30 -0200 Subject: [PATCH] Update fcp, add support for pointers to declarations --- .../clang-plugin/clang-plugin-version.config | 2 +- infer/src/clang/ast_expressions.ml | 39 +++++++++++-------- infer/src/clang/ast_expressions.mli | 4 +- infer/src/clang/cFrontend_utils.ml | 3 ++ infer/src/clang/cFrontend_utils.mli | 2 + infer/src/clang/objcProperty_decl.ml | 7 ++-- 6 files changed, 34 insertions(+), 23 deletions(-) diff --git a/dependencies/clang-plugin/clang-plugin-version.config b/dependencies/clang-plugin/clang-plugin-version.config index ad2682ef2..0837442d2 100644 --- a/dependencies/clang-plugin/clang-plugin-version.config +++ b/dependencies/clang-plugin/clang-plugin-version.config @@ -1 +1 @@ -8a70ebe9439ec6495330ebe9a90c45e8e8b6b3b7 +332177951f9004e44adb554b0ab31be4710c7d7e diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index 25fe3a3b1..72f2ef4e3 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -164,18 +164,17 @@ let make_name_decl name = { Clang_ast_t.ni_qual_name = [name]; } -let make_general_decl_ref k name is_hidden qt = { +let make_general_decl_ref k decl_ptr name is_hidden qt = { Clang_ast_t.dr_kind = k; + Clang_ast_t.dr_decl_pointer = decl_ptr; Clang_ast_t.dr_name = Some (make_name_decl name); Clang_ast_t.dr_is_hidden = is_hidden ; Clang_ast_t.dr_qual_type = Some (qt) } -let make_decl_ref name = - make_general_decl_ref (`Var) name false (create_int_type ()) - -let make_decl_ref_self qt = { +let make_decl_ref_self ptr qt = { Clang_ast_t.dr_kind = `ImplicitParam; + Clang_ast_t.dr_decl_pointer = ptr; Clang_ast_t.dr_name = Some (make_name_decl "self"); Clang_ast_t.dr_is_hidden = false ; Clang_ast_t.dr_qual_type = Some qt @@ -186,8 +185,8 @@ let make_decl_ref_expr_info decl_ref = { Clang_ast_t.drti_found_decl_ref = None; } -let make_obj_c_ivar_ref_expr_info k n qt = { - Clang_ast_t.ovrei_decl_ref = make_general_decl_ref k n false qt; +let make_obj_c_ivar_ref_expr_info k ptr n qt = { + Clang_ast_t.ovrei_decl_ref = make_general_decl_ref k ptr n false qt; Clang_ast_t.ovrei_pointer = Ast_utils.get_fresh_pointer (); Clang_ast_t.ovrei_is_free_ivar = true; } @@ -209,8 +208,9 @@ let make_self_field class_type di qt field_name = let qt_class = create_qual_type class_type in let expr_info = make_expr_info_with_objc_kind qt `ObjCProperty in let stmt_info = make_stmt_info di in - let cast_exp = make_cast_expr qt_class di (make_decl_ref_expr_info (make_decl_ref_self qt_class)) `ObjCProperty in - let obj_c_ivar_ref_expr_info = make_obj_c_ivar_ref_expr_info (`ObjCIvar) field_name qt in + let decl_ptr = Ast_utils.get_invalid_pointer() in + let cast_exp = make_cast_expr qt_class di (make_decl_ref_expr_info (make_decl_ref_self decl_ptr qt_class)) `ObjCProperty in + let obj_c_ivar_ref_expr_info = make_obj_c_ivar_ref_expr_info (`ObjCIvar) decl_ptr field_name qt in let ivar_ref_exp = ObjCIvarRefExpr(stmt_info, [cast_exp], expr_info, obj_c_ivar_ref_expr_info) in ivar_ref_exp @@ -254,9 +254,9 @@ let make_expr_info qt = Clang_ast_t.ei_object_kind = `ObjCProperty } -let make_decl_ref_exp_var (var_name, var_qt) var_kind stmt_info = +let make_decl_ref_exp_var (var_name, var_qt, var_ptr) var_kind stmt_info = let stmt_info = stmt_info_with_fresh_pointer stmt_info in - let decl_ref = make_general_decl_ref var_kind var_name false var_qt in + let decl_ref = make_general_decl_ref var_kind var_ptr var_name false var_qt in let expr_info = make_expr_info var_qt in make_decl_ref_exp stmt_info expr_info (make_decl_ref_expr_info decl_ref) @@ -282,8 +282,10 @@ let make_binary_stmt stmt1 stmt2 stmt_info expr_info boi = let make_next_object_exp stmt_info item items = let var_decl_ref, var_type = match item with - | DeclStmt (stmt_info, _, [VarDecl(di, var_name, var_type, _)]) -> - let decl_ref = make_general_decl_ref `Var var_name.Clang_ast_t.ni_name false var_type in + | DeclStmt (stmt_info, _, [VarDecl(di, name_info, var_type, _)]) -> + let var_name = name_info.Clang_ast_t.ni_name in + let decl_ptr = di.Clang_ast_t.di_pointer in + let decl_ref = make_general_decl_ref `Var decl_ptr var_name false var_type in let stmt_info_var = { si_pointer = di.Clang_ast_t.di_pointer; si_source_range = di.Clang_ast_t.di_source_range @@ -332,6 +334,7 @@ let translate_dispatch_function block_name stmt_info stmt_list ei n = } in let decl_ref = { dr_kind = `Var; + dr_decl_pointer = decl_info.di_pointer; dr_name = Some block_name_info; dr_is_hidden = false; dr_qual_type = Some qt; @@ -353,14 +356,14 @@ let trans_negation_with_conditional stmt_info expr_info stmt_list = let stmt_list_cond = stmt_list @ [create_integer_literal stmt_info "0"] @ [create_integer_literal stmt_info "1"] in ConditionalOperator(stmt_info, stmt_list_cond, expr_info) -let create_call stmt_info function_name qt parameters = +let create_call stmt_info decl_pointer function_name qt parameters = let expr_info_call = { Clang_ast_t.ei_qual_type = qt; Clang_ast_t.ei_value_kind = `XValue; Clang_ast_t.ei_object_kind = `Ordinary } in let expr_info_dre = make_expr_info_with_objc_kind qt `Ordinary in - let decl_ref = make_general_decl_ref `Function function_name false qt in + let decl_ref = make_general_decl_ref `Function decl_pointer function_name false qt in let decl_ref_info = make_decl_ref_expr_info decl_ref in let decl_ref_exp = DeclRefExpr(stmt_info, [], expr_info_dre, decl_ref_info) in CallExpr(stmt_info, decl_ref_exp:: parameters, expr_info_call) @@ -368,10 +371,12 @@ let create_call stmt_info function_name qt parameters = let create_assume_not_null_call decl_info var_name var_type = let stmt_info = stmt_info_with_fresh_pointer (make_stmt_info decl_info) in let boi = { Clang_ast_t.boi_kind = `NE } in - let decl_ref = make_general_decl_ref `Var var_name false var_type in + let decl_ptr = Ast_utils.get_invalid_pointer () in + let decl_ref = make_general_decl_ref `Var decl_ptr var_name false var_type in let stmt_info_var = dummy_stmt_info () in let decl_ref_info = make_decl_ref_expr_info decl_ref in let var_decl_ref = DeclRefExpr(stmt_info_var, [], (make_expr_info var_type), decl_ref_info) in + let var_decl_ptr = Ast_utils.get_invalid_pointer () in let expr_info = { Clang_ast_t.ei_qual_type = var_type; Clang_ast_t.ei_value_kind = `RValue; @@ -382,4 +387,4 @@ let create_assume_not_null_call decl_info var_name var_type = let null_expr = create_integer_literal stmt_info "0" in let bin_op = make_binary_stmt decl_ref_exp_cast null_expr stmt_info (make_expr_info var_type) boi in let parameters = [bin_op] in - create_call stmt_info (Procname.to_string SymExec.ModelBuiltins.__infer_assume) (create_void_type ()) parameters + create_call stmt_info var_decl_ptr (Procname.to_string SymExec.ModelBuiltins.__infer_assume) (create_void_type ()) parameters diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index ed238b1fb..0dde47fba 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -27,7 +27,7 @@ val make_stmt_info : decl_info -> stmt_info val make_method_decl_info : obj_c_method_decl_info -> stmt -> obj_c_method_decl_info -val make_general_decl_ref : decl_kind -> string -> bool -> qual_type -> decl_ref +val make_general_decl_ref : decl_kind -> pointer -> string -> bool -> qual_type -> decl_ref val make_decl_ref_expr_info : decl_ref -> decl_ref_expr_info @@ -49,7 +49,7 @@ val make_message_expr : qual_type -> string -> stmt -> stmt_info -> bool -> stmt val make_compound_stmt : stmt list -> stmt_info -> stmt -val make_decl_ref_exp_var : string * qual_type -> decl_kind -> stmt_info -> stmt +val make_decl_ref_exp_var : string * qual_type * pointer -> decl_kind -> stmt_info -> stmt val make_binary_stmt : stmt -> stmt -> stmt_info -> expr_info -> binary_operator_info -> stmt diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index c2fc6fb45..d1e0df246 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -239,6 +239,9 @@ struct pointer_counter := !pointer_counter + 1; CFrontend_config.pointer_prefix^(string_of_int (!pointer_counter)) + let get_invalid_pointer () = + CFrontend_config.pointer_prefix^("INVALID") + let type_from_unary_expr_or_type_trait_expr_info info = match info.uttei_qual_type with | Some qt -> Some qt diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index 6ce7023f7..e2b0649d8 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -63,6 +63,8 @@ sig val get_fresh_pointer : unit -> string + val get_invalid_pointer : unit -> string + val type_from_unary_expr_or_type_trait_expr_info : Clang_ast_t.unary_expr_or_type_trait_expr_info -> Clang_ast_t.qual_type option diff --git a/infer/src/clang/objcProperty_decl.ml b/infer/src/clang/objcProperty_decl.ml index 9fa4fb888..3dcaa46a5 100644 --- a/infer/src/clang/objcProperty_decl.ml +++ b/infer/src/clang/objcProperty_decl.ml @@ -300,8 +300,9 @@ let make_getter_setter cfg curr_class decl_info property_impl_decl_info = let is_hidden = (match property_impl_decl_info.Clang_ast_t.opidi_ivar_decl with | Some dr -> dr.Clang_ast_t.dr_is_hidden | _ -> false) in + let decl_ptr = Ast_utils.get_invalid_pointer () in let drti_decl_ref' = - Ast_expressions.make_general_decl_ref (`ParmVar) param_name is_hidden qt_param in + Ast_expressions.make_general_decl_ref (`ParmVar) decl_ptr param_name is_hidden qt_param in let decl_ref_expr_info' = Ast_expressions.make_decl_ref_expr_info drti_decl_ref' in let expr_info = Ast_expressions.make_expr_info qt_param in let stmt_info = Ast_expressions.make_stmt_info dummy_info in @@ -314,7 +315,7 @@ let make_getter_setter cfg curr_class decl_info property_impl_decl_info = let code = if Ast_utils.is_retain memory_management_attribute then let param_decl = - Ast_expressions.make_decl_ref_exp_var (param_name, qt_param) `ParmVar stmt_info in + Ast_expressions.make_decl_ref_exp_var (param_name, qt_param, decl_ptr) `ParmVar stmt_info in let retain_call = Ast_expressions.make_message_expr qt_param retain param_decl stmt_info true in let release_call = @@ -322,7 +323,7 @@ let make_getter_setter cfg curr_class decl_info property_impl_decl_info = [retain_call; release_call; setter] else if Ast_utils.is_copy memory_management_attribute then let param_decl = - Ast_expressions.make_decl_ref_exp_var (param_name, qt_param) `ParmVar stmt_info in + Ast_expressions.make_decl_ref_exp_var (param_name, qt_param, decl_ptr) `ParmVar stmt_info in let copy_call = Ast_expressions.make_message_expr qt_param copy param_decl stmt_info true in let setter =