From 3b3f587652660f532f030e11fd65ad4480dc8855 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Tue, 9 Aug 2016 16:20:28 -0700 Subject: [PATCH] update fcp to have qualifiers in ValueDecl types Summary: Make necessary changes so that the clang frontend compiles with the corresponding changes to the facebook clang plugins. Does not actually use the extra qualifier information yet. depends on D3684150 Reviewed By: akotulski Differential Revision: D3684173 fbshipit-source-id: f715f75 --- facebook-clang-plugins | 2 +- infer/src/clang/ast_expressions.ml | 45 +++++++++++++++++---------- infer/src/clang/ast_expressions.mli | 2 +- infer/src/clang/cField_decl.ml | 5 +-- infer/src/clang/cFrontend_checkers.ml | 8 ++--- infer/src/clang/cMethod_trans.ml | 24 +++++++------- infer/src/clang/cTrans.ml | 8 +++-- infer/src/clang/cTypes_decl.ml | 4 +-- infer/src/clang/cVar_decl.ml | 10 +++--- 9 files changed, 64 insertions(+), 44 deletions(-) diff --git a/facebook-clang-plugins b/facebook-clang-plugins index e7a039132..62448f69c 160000 --- a/facebook-clang-plugins +++ b/facebook-clang-plugins @@ -1 +1 @@ -Subproject commit e7a03913245a000c683182fa8fe131b0b4bc36a3 +Subproject commit 62448f69cf2de26a7a7599d3cec30c9446890674 diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index 8f63d9e27..8077b736f 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -110,6 +110,8 @@ let create_struct_type struct_name = `StructType struct_name let create_pointer_type typ = `PointerOf typ +let create_qual_type ?(is_const=false) type_ptr = { Clang_ast_t.type_ptr; is_const } + let create_reference_type typ = `ReferenceOf typ let create_integer_literal n = @@ -237,7 +239,8 @@ let make_objc_ivar_decl decl_info tp ivar_name = Clang_ast_t.ovdi_is_synthesize = true; (* NOTE: We set true here because we use this definition to synthesize the getter/setter*) ovdi_access_control = `Private; } in - Clang_ast_t.ObjCIvarDecl(decl_info, ivar_name, tp, field_decl_info, obj_c_ivar_decl_info) + let qt = create_qual_type tp in + Clang_ast_t.ObjCIvarDecl (decl_info, ivar_name, qt, field_decl_info, obj_c_ivar_decl_info) let make_expr_info tp = { Clang_ast_t.ei_type_ptr = tp; @@ -273,7 +276,8 @@ 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 - | Clang_ast_t.DeclStmt (_, _, [Clang_ast_t.VarDecl(di, name_info, var_type, _)]) -> + | Clang_ast_t.DeclStmt (_, _, [Clang_ast_t.VarDecl(di, name_info, var_qual_type, _)]) -> + let var_type = var_qual_type.Clang_ast_t.type_ptr in let decl_ptr = di.Clang_ast_t.di_pointer in let decl_ref = make_decl_ref_tp `Var decl_ptr name_info false var_type in let stmt_info_var = { @@ -316,7 +320,8 @@ let make_DeclStmt stmt_info di tp vname old_vdi iexp = | None -> None, [] in let var_decl_info = { old_vdi with Clang_ast_t.vdi_init_expr = init_expr_opt } in let di = fresh_decl_info di in - let var_decl = Clang_ast_t.VarDecl (di, vname, tp, var_decl_info) in + let qt = create_qual_type tp in + let var_decl = Clang_ast_t.VarDecl (di, vname, qt, var_decl_info) in Clang_ast_t.DeclStmt (stmt_info, init_expr_l, [var_decl]) let build_OpaqueValueExpr si source_expr ei = @@ -393,9 +398,10 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = let build_idx_decl pidx = match pidx with - | Clang_ast_t.ParmVarDecl (di_idx, name_idx, tp_idx, vdi) -> + | Clang_ast_t.ParmVarDecl (di_idx, name_idx, qt_idx, vdi) -> let zero = create_integer_literal "0" in - (* tp_idx idx = 0; *) + (* qt_idx idx = 0; *) + let tp_idx = qt_idx.Clang_ast_t.type_ptr in let idx_decl_stmt = make_DeclStmt (fresh_stmt_info stmt_info) di_idx tp_idx name_idx vdi (Some zero) in let idx_ei = make_expr_info tp_idx in @@ -417,7 +423,7 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = (* build statement BOOL *stop = malloc(sizeof(BOOL)); *) let build_stop pstop = match pstop with - | Clang_ast_t.ParmVarDecl (di, name, tp, vdi) -> + | Clang_ast_t.ParmVarDecl (di, name, qt, vdi) -> let tp_fun = create_void_unsigned_long_type in let type_opt = Some create_BOOL_type in let parameter = Clang_ast_t.UnaryExprOrTypeTraitExpr @@ -428,6 +434,7 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = let stmt_info = fresh_stmt_info stmt_info in let malloc_name = Ast_utils.make_name_decl CFrontend_config.malloc in let malloc = create_call stmt_info pointer malloc_name tp_fun [parameter] in + let tp = qt.Clang_ast_t.type_ptr in let init_exp = create_implicit_cast_expr (fresh_stmt_info stmt_info) [malloc] tp `BitCast in make_DeclStmt (fresh_stmt_info stmt_info) di tp name vdi (Some init_exp) | _ -> assert false in @@ -435,7 +442,8 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = (* BOOL *stop =NO; *) let stop_equal_no pstop = match pstop with - | Clang_ast_t.ParmVarDecl (di, name, tp, _) -> + | Clang_ast_t.ParmVarDecl (di, name, qt, _) -> + let tp = qt.Clang_ast_t.type_ptr in let decl_ref = make_decl_ref_tp `Var di.Clang_ast_t.di_pointer name false tp in let cast = cast_expr decl_ref tp in let postfix_deref = { Clang_ast_t.uoi_kind = `Deref; uoi_is_postfix = true } in @@ -448,7 +456,8 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = (* build statement free(stop); *) let free_stop pstop = match pstop with - | Clang_ast_t.ParmVarDecl (di, name, tp, _) -> + | Clang_ast_t.ParmVarDecl (di, name, qt, _) -> + let tp = qt.Clang_ast_t.type_ptr in let tp_fun = create_void_void_type in let decl_ref = make_decl_ref_tp `Var di.Clang_ast_t.di_pointer name false tp in let cast = cast_expr decl_ref tp in @@ -482,7 +491,8 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = let build_object_DeclStmt pobj decl_ref_expr_array decl_ref_expr_idx = let open Clang_ast_t in match pobj with - | ParmVarDecl(di_obj, name_obj, tp_obj, _) -> + | ParmVarDecl(di_obj, name_obj, qt_obj, _) -> + let tp_obj = qt_obj.Clang_ast_t.type_ptr in let poe_ei = make_general_expr_info tp_obj `RValue `Ordinary in let ei_array = get_ei_from_cast decl_ref_expr_array in let ove_array = build_OpaqueValueExpr (fresh_stmt_info stmt_info) decl_ref_expr_array ei_array in @@ -495,14 +505,15 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = let ome = ObjCMessageExpr (fresh_stmt_info stmt_info, [ove_array; ove_idx], poe_ei, obj_c_message_expr_info) in let pseudo_obj_expr = PseudoObjectExpr (fresh_stmt_info stmt_info, [objc_sre; ove_array; ove_idx; ome], poe_ei) in let vdi = { empty_var_decl_info with vdi_init_expr = Some (pseudo_obj_expr) } in - let var_decl = VarDecl (di_obj, name_obj, tp_obj, vdi) in + let var_decl = VarDecl (di_obj, name_obj, qt_obj, vdi) in DeclStmt (fresh_stmt_info stmt_info, [pseudo_obj_expr], [var_decl]) | _ -> assert false in (* NSArray *objects = a *) let objects_array_DeclStmt init = let di = { empty_decl_info with Clang_ast_t.di_pointer = Ast_utils.get_fresh_pointer () } in - let tp = create_pointer_type (create_class_type (CFrontend_config.nsarray_cl, `OBJC)) in + let tp = create_qual_type @@ create_pointer_type @@ create_class_type + (CFrontend_config.nsarray_cl, `OBJC) in (* init should be ImplicitCastExpr of array a *) let vdi = { empty_var_decl_info with Clang_ast_t.vdi_init_expr = Some (init) } in let objects_name = Ast_utils.make_name_decl CFrontend_config.objects in @@ -511,14 +522,16 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = let make_object_cast_decl_ref_expr objects = match objects with - | Clang_ast_t.DeclStmt (si, _, [Clang_ast_t.VarDecl (_, name, tp, _)]) -> + | Clang_ast_t.DeclStmt (si, _, [Clang_ast_t.VarDecl (_, name, qt, _)]) -> + let tp = qt.Clang_ast_t.type_ptr in let decl_ref = make_decl_ref_tp `Var si.Clang_ast_t.si_pointer name false tp in cast_expr decl_ref tp | _ -> assert false in let build_cast_decl_ref_expr_from_parm p = match p with - | Clang_ast_t.ParmVarDecl (di, name, tp, _) -> + | Clang_ast_t.ParmVarDecl (di, name, qt, _) -> + let tp = qt.Clang_ast_t.type_ptr in let decl_ref = make_decl_ref_tp `Var di.Clang_ast_t.di_pointer name false tp in cast_expr decl_ref tp | _ -> assert false in @@ -530,9 +543,9 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = | Clang_ast_t.BlockExpr (bsi, _, bei, _) -> let di = { empty_decl_info with Clang_ast_t.di_pointer = Ast_utils.get_fresh_pointer () } in let vdi = { empty_var_decl_info with Clang_ast_t.vdi_init_expr = Some (be) } in - let tp = bei.Clang_ast_t.ei_type_ptr in - let var_decl = Clang_ast_t.VarDecl (di, qual_block_name, tp, vdi) in - Clang_ast_t.DeclStmt (bsi, [be], [var_decl]), [(block_name, di.Clang_ast_t.di_pointer, bei.Clang_ast_t.ei_type_ptr)] + let qt = create_qual_type bei.Clang_ast_t.ei_type_ptr in + let var_decl = Clang_ast_t.VarDecl (di, qual_block_name, qt, vdi) in + Clang_ast_t.DeclStmt (bsi, [be], [var_decl]), [(block_name, di.Clang_ast_t.di_pointer, qt)] | _ -> assert false in let make_block_call block_tp object_cast idx_cast stop_cast = diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index aa03f0455..aaa941d06 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -82,7 +82,7 @@ val make_obj_c_message_expr_info_instance : string -> obj_c_message_expr_info val translate_dispatch_function : stmt_info -> stmt list -> int -> stmt val translate_block_enumerate : string -> stmt_info -> stmt list -> expr_info -> - stmt * (string * Clang_ast_t.pointer * type_ptr) list + stmt * (string * Clang_ast_t.pointer * qual_type) list (* We translate the logical negation of an integer with a conditional*) (* !x <=> x?0:1 *) diff --git a/infer/src/clang/cField_decl.ml b/infer/src/clang/cField_decl.ml index bbd2b4d53..c07faf4a1 100644 --- a/infer/src/clang/cField_decl.ml +++ b/infer/src/clang/cField_decl.ml @@ -55,9 +55,10 @@ let build_sil_field type_ptr_to_sil_type tenv field_name type_ptr prop_attribute (* Given a list of declarations in an interface returns a list of fields *) let rec get_fields type_ptr_to_sil_type tenv curr_class decl_list = let open Clang_ast_t in - let add_field name_info type_ptr attributes decl_list' = + let add_field name_info qt attributes decl_list' = let fields = get_fields type_ptr_to_sil_type tenv curr_class decl_list' in - let field_tuple = build_sil_field type_ptr_to_sil_type tenv name_info type_ptr attributes in + let field_tuple = build_sil_field type_ptr_to_sil_type tenv + name_info qt.Clang_ast_t.type_ptr attributes in General_utils.append_no_duplicates_fields [field_tuple] fields in match decl_list with | [] -> [] diff --git a/infer/src/clang/cFrontend_checkers.ml b/infer/src/clang/cFrontend_checkers.ml index 2232b2607..cac023817 100644 --- a/infer/src/clang/cFrontend_checkers.ml +++ b/infer/src/clang/cFrontend_checkers.ml @@ -141,10 +141,10 @@ let captured_variables_cxx_ref captured_vars = let capture_var_is_cxx_ref reference_captured_vars captured_var = let decl_ref_opt = captured_var.Clang_ast_t.bcv_variable in match Ast_utils.get_decl_opt_with_decl_ref decl_ref_opt with - | Some VarDecl (_, named_decl_info, type_ptr, _) - | Some ParmVarDecl (_, named_decl_info, type_ptr, _) - | Some ImplicitParamDecl (_, named_decl_info, type_ptr, _) -> - (match Ast_utils.get_desugared_type type_ptr with + | Some VarDecl (_, named_decl_info, qual_type, _) + | Some ParmVarDecl (_, named_decl_info, qual_type, _) + | Some ImplicitParamDecl (_, named_decl_info, qual_type, _) -> + (match Ast_utils.get_desugared_type qual_type.Clang_ast_t.type_ptr with | Some RValueReferenceType _ | Some LValueReferenceType _ -> named_decl_info::reference_captured_vars | _ -> reference_captured_vars) diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index c426e79bf..b06933972 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -108,8 +108,9 @@ let is_cpp_virtual function_method_decl_info = let get_parameters tenv function_method_decl_info = let par_to_ms_par par = match par with - | Clang_ast_t.ParmVarDecl (_, name_info, type_ptr, var_decl_info) -> + | Clang_ast_t.ParmVarDecl (_, name_info, qt, var_decl_info) -> let _, mangled = General_utils.get_var_name_mangled name_info var_decl_info in + let type_ptr = qt.Clang_ast_t.type_ptr in let param_typ = CTypes_decl.type_ptr_to_sil_type tenv type_ptr in let type_ptr' = match param_typ with | Typ.Tstruct _ when General_utils.is_cpp_translation Config.clang_lang -> @@ -144,9 +145,10 @@ let build_method_signature tenv decl_info procname function_method_decl_info let get_assume_not_null_calls param_decls = let do_one_param decl = match decl with - | Clang_ast_t.ParmVarDecl (decl_info, name, tp, _) - when CFrontend_utils.Ast_utils.is_type_nonnull tp -> - let assume_call = Ast_expressions.create_assume_not_null_call decl_info name tp in + | Clang_ast_t.ParmVarDecl (decl_info, name, qt, _) + when CFrontend_utils.Ast_utils.is_type_nonnull qt.Clang_ast_t.type_ptr -> + let assume_call = Ast_expressions.create_assume_not_null_call + decl_info name qt.Clang_ast_t.type_ptr in [(`ClangStmt assume_call)] | _ -> [] in IList.flatten (IList.map do_one_param param_decls) @@ -158,20 +160,20 @@ let get_init_list_instrs method_decl_info = let method_signature_of_decl tenv meth_decl block_data_opt = let open Clang_ast_t in match meth_decl, block_data_opt with - | FunctionDecl (decl_info, _, tp, fdi), _ -> + | FunctionDecl (decl_info, _, qt, fdi), _ -> let language = Config.clang_lang in - let func_decl = Func_decl_info (fdi, tp, language) in + let func_decl = Func_decl_info (fdi, qt.Clang_ast_t.type_ptr, language) in let procname = General_utils.procname_of_decl meth_decl in let ms = build_method_signature tenv decl_info procname func_decl None None in let extra_instrs = get_assume_not_null_calls fdi.Clang_ast_t.fdi_parameters in ms, fdi.Clang_ast_t.fdi_body, extra_instrs - | CXXMethodDecl (decl_info, _, tp, fdi, mdi), _ - | CXXConstructorDecl (decl_info, _, tp, fdi, mdi), _ - | CXXConversionDecl (decl_info, _, tp, fdi, mdi), _ - | CXXDestructorDecl (decl_info, _, tp, fdi, mdi), _ -> + | CXXMethodDecl (decl_info, _, qt, fdi, mdi), _ + | CXXConstructorDecl (decl_info, _, qt, fdi, mdi), _ + | CXXConversionDecl (decl_info, _, qt, fdi, mdi), _ + | CXXDestructorDecl (decl_info, _, qt, fdi, mdi), _ -> let procname = General_utils.procname_of_decl meth_decl in let parent_ptr = Option.get decl_info.di_parent_pointer in - let method_decl = Cpp_Meth_decl_info (fdi, mdi, parent_ptr, tp) in + let method_decl = Cpp_Meth_decl_info (fdi, mdi, parent_ptr, qt.Clang_ast_t.type_ptr) in let parent_pointer = decl_info.Clang_ast_t.di_parent_pointer in let ms = build_method_signature tenv decl_info procname method_decl parent_pointer None in let non_null_instrs = get_assume_not_null_calls fdi.Clang_ast_t.fdi_parameters in diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 7e8f41165..5135138a9 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1679,10 +1679,12 @@ struct let context = trans_state.context in let procdesc = context.CContext.procdesc in let procname = Cfg.Procdesc.get_proc_name procdesc in - let do_var_dec (di, var_name, type_ptr, vdi) next_node = - let var_decl = VarDecl (di, var_name, type_ptr, vdi) in + let do_var_dec (di, var_name, qual_type, vdi) next_node = + let var_decl = VarDecl (di, var_name, qual_type, vdi) in let pvar = CVar_decl.sil_var_of_decl context var_decl procname in - let typ = CTypes_decl.type_ptr_to_sil_type context.CContext.tenv type_ptr in + let typ = CTypes_decl.type_ptr_to_sil_type + context.CContext.tenv + qual_type.Clang_ast_t.type_ptr in CVar_decl.add_var_to_locals procdesc var_decl typ pvar; let trans_state' = { trans_state with succ_nodes = next_node } in init_expr_trans trans_state' (Exp.Lvar pvar, typ) stmt_info vdi.Clang_ast_t.vdi_init_expr in diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index d54a13274..1cce9894e 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -155,9 +155,9 @@ let rec get_struct_fields tenv decl = | RecordDecl (_, _, _, _, decl_list, _, _) -> decl_list | _ -> [] in let do_one_decl decl = match decl with - | FieldDecl (_, name_info, type_ptr, _) -> + | FieldDecl (_, name_info, qt, _) -> let id = General_utils.mk_class_field_name name_info in - let typ = type_ptr_to_sil_type tenv type_ptr in + let typ = type_ptr_to_sil_type tenv qt.Clang_ast_t.type_ptr in let annotation_items = [] in (* For the moment we don't use them*) [(id, typ, annotation_items)] | _ -> [] in diff --git a/infer/src/clang/cVar_decl.ml b/infer/src/clang/cVar_decl.ml index b87d0831e..3f9c2f93e 100644 --- a/infer/src/clang/cVar_decl.ml +++ b/infer/src/clang/cVar_decl.ml @@ -23,13 +23,15 @@ let sil_var_of_decl context var_decl procname = let outer_procname = CContext.get_outer_procname context in let open Clang_ast_t in match var_decl with - | VarDecl (decl_info, name_info, type_ptr, var_decl_info) -> + | VarDecl (decl_info, name_info, qual_type, var_decl_info) -> let shoud_be_mangled = not (is_custom_var_pointer decl_info.Clang_ast_t.di_pointer) in - let var_decl_details = Some (decl_info, type_ptr, var_decl_info, shoud_be_mangled) in + let var_decl_details = Some + (decl_info, qual_type.Clang_ast_t.type_ptr, var_decl_info, shoud_be_mangled) in General_utils.mk_sil_var name_info var_decl_details procname outer_procname - | ParmVarDecl (decl_info, name_info, type_ptr, var_decl_info) -> - let var_decl_details = Some (decl_info, type_ptr, var_decl_info, false) in + | ParmVarDecl (decl_info, name_info, qual_type, var_decl_info) -> + let var_decl_details = Some + (decl_info, qual_type.Clang_ast_t.type_ptr, var_decl_info, false) in General_utils.mk_sil_var name_info var_decl_details procname outer_procname | _ -> assert false