diff --git a/facebook-clang-plugins b/facebook-clang-plugins index 259d4e518..c7e476c39 160000 --- a/facebook-clang-plugins +++ b/facebook-clang-plugins @@ -1 +1 @@ -Subproject commit 259d4e518b31b1d8c78c744c87b5bbe4ba775882 +Subproject commit c7e476c39601eaf3ccaff272006c7da799cac208 diff --git a/infer/src/IR/Typ.re b/infer/src/IR/Typ.re index f8f4d24f1..7ff52f148 100644 --- a/infer/src/IR/Typ.re +++ b/infer/src/IR/Typ.re @@ -123,7 +123,7 @@ let ptr_kind_string = type static_length = option IntLit.t [@@deriving compare]; module T = { - type type_quals = {is_const: bool, is_volatile: bool} [@@deriving compare]; + type type_quals = {is_const: bool, is_restrict: bool, is_volatile: bool} [@@deriving compare]; /** types for sil (structured) expressions */ type t = {desc, quals: type_quals} [@@deriving compare] @@ -156,17 +156,25 @@ module T = { include T; -let mk_type_quals ::default=? ::is_const=? ::is_volatile=? () => { - let default_ = {is_const: false, is_volatile: false}; - let mk_aux ::default=default_ ::is_const=default.is_const ::is_volatile=default.is_volatile () => { +let mk_type_quals ::default=? ::is_const=? ::is_restrict=? ::is_volatile=? () => { + let default_ = {is_const: false, is_restrict: false, is_volatile: false}; + let mk_aux + ::default=default_ + ::is_const=default.is_const + ::is_restrict=default.is_restrict + ::is_volatile=default.is_volatile + () => { is_const, + is_restrict, is_volatile }; - mk_aux ::?default ::?is_const ::?is_volatile () + mk_aux ::?default ::?is_const ::?is_restrict ::?is_volatile () }; let is_const {is_const} => is_const; +let is_restrict {is_restrict} => is_restrict; + let is_volatile {is_volatile} => is_volatile; let mk ::default=? ::quals=? desc :t => { @@ -281,6 +289,9 @@ let rec pp_full pe f typ => { if (is_const quals) { F.fprintf f " const " }; + if (is_restrict quals) { + F.fprintf f " __restrict " + }; if (is_volatile quals) { F.fprintf f " volatile " } diff --git a/infer/src/IR/Typ.rei b/infer/src/IR/Typ.rei index f73bc2ffc..b74a589f7 100644 --- a/infer/src/IR/Typ.rei +++ b/infer/src/IR/Typ.rei @@ -72,12 +72,18 @@ type static_length = option IntLit.t [@@deriving compare]; type type_quals [@@deriving compare]; let mk_type_quals: - default::type_quals? => is_const::bool? => is_volatile::bool? => unit => type_quals; + default::type_quals? => + is_const::bool? => + is_restrict::bool? => + is_volatile::bool? => + unit => + type_quals; let is_const: type_quals => bool; -let is_volatile: type_quals => bool; +let is_restrict: type_quals => bool; +let is_volatile: type_quals => bool; /** types for sil (structured) expressions */ diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index f8908fb9c..0e7883145 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -63,17 +63,21 @@ let stmt_info_with_fresh_pointer stmt_info = { si_source_range = stmt_info.Clang_ast_t.si_source_range; } -let create_qual_type ?(is_const=false) qt_type_ptr = - { Clang_ast_t.qt_type_ptr; qt_is_const=is_const } +let create_qual_type ?(quals=Typ.mk_type_quals ()) qt_type_ptr = + { Clang_ast_t.qt_type_ptr; + qt_is_const=Typ.is_const quals; + qt_is_volatile=Typ.is_volatile quals; + qt_is_restrict=Typ.is_restrict quals; + } let builtin_to_qual_type kind = create_qual_type (Clang_ast_extend.Builtin kind) -let create_pointer_qual_type ~is_const typ = - create_qual_type ~is_const (Clang_ast_extend.PointerOf typ) +let create_pointer_qual_type ?quals typ = + create_qual_type ?quals (Clang_ast_extend.PointerOf typ) -let create_reference_qual_type ~is_const typ = - create_qual_type ~is_const (Clang_ast_extend.ReferenceOf typ) +let create_reference_qual_type ?quals typ = + create_qual_type ?quals (Clang_ast_extend.ReferenceOf typ) (* We translate function types as the return type of the function *) let function_type_ptr return_type = return_type @@ -82,12 +86,12 @@ let create_int_type = builtin_to_qual_type `Int let create_void_type = builtin_to_qual_type `Void -let create_void_star_type = create_pointer_qual_type ~is_const:false create_void_type +let create_void_star_type = create_pointer_qual_type create_void_type -let create_id_type = create_pointer_qual_type ~is_const:false (builtin_to_qual_type `ObjCId) +let create_id_type = create_pointer_qual_type (builtin_to_qual_type `ObjCId) let create_char_type = builtin_to_qual_type `Char_S -let create_char_star_type ~is_const = create_pointer_qual_type ~is_const create_char_type +let create_char_star_type ?quals () = create_pointer_qual_type ?quals create_char_type let create_BOOL_type = builtin_to_qual_type `SChar @@ -97,8 +101,8 @@ let create_void_unsigned_long_type = function_type_ptr create_void_type let create_void_void_type = function_type_ptr create_void_type -let create_class_qual_type ?(is_const=false) typename = - create_qual_type ~is_const (Clang_ast_extend.ClassType typename) +let create_class_qual_type ?quals typename = + create_qual_type ?quals (Clang_ast_extend.ClassType typename) let make_objc_class_qual_type class_name = create_class_qual_type (Typ.Name.Objc.from_string class_name) @@ -480,8 +484,7 @@ let translate_block_enumerate block_name stmt_info stmt_list ei = (* NSArray *objects = a *) let objects_array_DeclStmt init = let di = { empty_decl_info with Clang_ast_t.di_pointer = CAst_utils.get_fresh_pointer () } in - let qt = create_pointer_qual_type ~is_const:false @@ - make_objc_class_qual_type CFrontend_config.nsarray_cl in + let qt = create_pointer_qual_type (make_objc_class_qual_type CFrontend_config.nsarray_cl) 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 = CAst_utils.make_name_decl CFrontend_config.objects in diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index ce86ec205..03b446cb9 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -19,13 +19,13 @@ val dummy_source_range : unit -> source_range val dummy_stmt_info : unit -> stmt_info -val create_class_qual_type : ?is_const:bool -> Typ.Name.t -> qual_type +val create_class_qual_type : ?quals:Typ.type_quals -> Typ.Name.t -> qual_type -val create_pointer_qual_type : is_const:bool -> qual_type -> qual_type +val create_pointer_qual_type : ?quals:Typ.type_quals -> qual_type -> qual_type -val create_reference_qual_type : is_const:bool -> qual_type -> qual_type +val create_reference_qual_type : ?quals:Typ.type_quals -> qual_type -> qual_type -val create_char_star_type : is_const:bool -> qual_type +val create_char_star_type : ?quals:Typ.type_quals -> unit -> qual_type val create_id_type : qual_type diff --git a/infer/src/clang/cAst_utils.ml b/infer/src/clang/cAst_utils.ml index 44ad1082d..671f39dd3 100644 --- a/infer/src/clang/cAst_utils.ml +++ b/infer/src/clang/cAst_utils.ml @@ -183,7 +183,9 @@ let qual_type_of_decl_ptr decl_ptr = { (* This function needs to be in this module - CAst_utils can't depend on Ast_expressions *) Clang_ast_t.qt_type_ptr=Clang_ast_extend.DeclPtr decl_ptr; - qt_is_const=false + qt_is_const=false; + qt_is_volatile=false; + qt_is_restrict=false; } let add_type_from_decl_ref qual_type_to_sil_type tenv dr = diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 93113f0f5..cbea2213f 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -77,7 +77,7 @@ let get_return_param tenv function_method_decl_info = let return_typ = CType_decl.qual_type_to_sil_type tenv return_qual_type in if should_add_return_param return_typ ~is_objc_method then [(Mangled.from_string CFrontend_config.return_param, - Ast_expressions.create_pointer_qual_type ~is_const:false return_qual_type)] + Ast_expressions.create_pointer_qual_type return_qual_type)] else [] @@ -114,7 +114,7 @@ let get_parameters trans_unit_ctx tenv function_method_decl_info = let new_qt = match param_typ.Typ.desc with | Tstruct _ when CGeneral_utils.is_cpp_translation trans_unit_ctx -> - Ast_expressions.create_reference_qual_type ~is_const:false qt + Ast_expressions.create_reference_qual_type qt | _ -> qt in (mangled, new_qt) | _ -> assert false in @@ -294,7 +294,7 @@ let get_formal_parameters tenv ms = (CMethod_signature.ms_get_lang ms) CFrontend_config.CPP in (is_objc_self && CMethod_signature.ms_is_instance ms) || is_cxx_this in let qt = if should_add_pointer (Mangled.to_string mangled) ms then - (Ast_expressions.create_pointer_qual_type ~is_const:false qual_type) + (Ast_expressions.create_pointer_qual_type qual_type) else qual_type in let typ = CType_decl.qual_type_to_sil_type tenv qt in (mangled, typ):: defined_parameters pl' in diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 1878125d2..1f00e0c89 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -1992,8 +1992,10 @@ struct instruction trans_state message_stmt and objCStringLiteral_trans trans_state stmt_info stmts info = - let stmts = [Ast_expressions.create_implicit_cast_expr stmt_info stmts - (Ast_expressions.create_char_star_type ~is_const:true) `ArrayToPointerDecay] in + let char_star_typ = + Ast_expressions.create_char_star_type ~quals:(Typ.mk_type_quals ~is_const:true ()) () in + let stmts = [Ast_expressions.create_implicit_cast_expr stmt_info stmts char_star_typ + `ArrayToPointerDecay] in let typ = CType_decl.class_from_pointer_type trans_state.context.CContext.tenv info.Clang_ast_t.ei_qual_type in @@ -2682,8 +2684,8 @@ struct let child_stmt_info = { (Ast_expressions.dummy_stmt_info ()) with Clang_ast_t.si_source_range = source_range } in let trans_state' = PriorityNode.try_claim_priority_node trans_state this_stmt_info in - let class_qual_type = Ast_expressions.create_pointer_qual_type ~is_const:false - (CAst_utils.qual_type_of_decl_ptr class_ptr) in + let class_qual_type = + Ast_expressions.create_pointer_qual_type (CAst_utils.qual_type_of_decl_ptr class_ptr) in let this_res_trans = this_expr_trans trans_state' sil_loc class_qual_type in let var_res_trans = match ctor_init.Clang_ast_t.xci_subject with | `Delegating _ | `BaseClass _ -> diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index e4b5921dd..2ecf1f588 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -149,8 +149,9 @@ let get_predefined_ms_stringWithUTF8String class_name method_name mk_procname la class_equal class_name CFrontend_config.nsstring_cl && String.equal method_name CFrontend_config.string_with_utf8_m in let id_type = Ast_expressions.create_id_type in - let args = [(Mangled.from_string "x", - Ast_expressions.create_char_star_type ~is_const:true)] in + let char_star_type = + Ast_expressions.create_char_star_type ~quals:(Typ.mk_type_quals ~is_const:true ()) () in + let args = [(Mangled.from_string "x", char_star_type)] in get_predefined_ms_method condition class_name method_name Typ.Procname.ObjCClassMethod mk_procname lang args id_type [] None diff --git a/infer/src/clang/clang_ast_extend.ml b/infer/src/clang/clang_ast_extend.ml index 68264c0eb..4849f50f6 100644 --- a/infer/src/clang/clang_ast_extend.ml +++ b/infer/src/clang/clang_ast_extend.ml @@ -48,10 +48,25 @@ module TypePointerOrd = struct | ErrorType, ErrorType -> 0 | _ -> raise (invalid_arg ("unexpected type_ptr variants: ")) and compare_qual_type (qt1 : Clang_ast_t.qual_type) (qt2 : Clang_ast_t.qual_type) = - let (<>) = Int.(<>) in - let qt_cmp = compare qt1.qt_type_ptr qt2.qt_type_ptr in - if qt_cmp <> 0 then qt_cmp else - Bool.compare qt1.qt_is_const qt2.qt_is_const + if phys_equal qt1 qt2 then 0 else + (* enable warning here to warn and update comparison funtion when new field is added *) + let [@warning "+9"] { + Clang_ast_t.qt_type_ptr = t1; + qt_is_const = c1; + qt_is_restrict = r1; + qt_is_volatile = v1} = qt1 in + let [@warning "+9"] { + Clang_ast_t.qt_type_ptr = t2; + qt_is_const = c2; + qt_is_restrict = r2; + qt_is_volatile = v2} = qt2 in + let qt_cmp = compare t1 t2 in + if qt_cmp <> 0 then qt_cmp else + let const_cmp = Bool.compare c1 c2 in + if const_cmp <> 0 then const_cmp else + let restrict_cmp = Bool.compare r1 r2 in + if restrict_cmp <> 0 then restrict_cmp else + Bool.compare v1 v2 end module TypePointerMap = Caml.Map.Make(TypePointerOrd)