[clang] Translate type qualifiers into Sil

Reviewed By: jberdine

Differential Revision: D4954391

fbshipit-source-id: 26685c0
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent 1b0ee6fbc3
commit aefbbe8680

@ -105,7 +105,7 @@ let rec get_struct_fields tenv decl =
and get_record_declaration_type tenv decl =
let definition_decl = get_record_definition decl in
match get_record_custom_type tenv definition_decl with
| Some t -> t
| Some t -> t.Typ.desc
| None -> get_record_struct_type tenv definition_decl
and get_record_custom_type tenv definition_decl =
@ -158,16 +158,16 @@ and get_superclass_list_cpp tenv decl =
let get_super_field super_decl = get_record_typename ~tenv super_decl in
List.map ~f:get_super_field base_decls
and get_record_struct_type tenv definition_decl : Typ.t =
and get_record_struct_type tenv definition_decl : Typ.desc =
let open Clang_ast_t in
match definition_decl with
| ClassTemplateSpecializationDecl (_, _, _, type_ptr, _, _, record_decl_info, _, _)
| CXXRecordDecl (_, _, _, type_ptr, _, _, record_decl_info, _)
| RecordDecl (_, _, _, type_ptr, _, _, record_decl_info) ->
let sil_typename = get_record_typename ~tenv definition_decl in
let sil_type = Typ.mk (Tstruct sil_typename) in
let sil_desc = Typ.Tstruct sil_typename in
(match Tenv.lookup tenv sil_typename with
| Some _ -> sil_type (* just reuse what is already in tenv *)
| Some _ -> sil_desc (* just reuse what is already in tenv *)
| None ->
let is_complete_definition = record_decl_info.Clang_ast_t.rdi_is_complete_definition in
let extra_fields =
@ -178,7 +178,7 @@ and get_record_struct_type tenv definition_decl : Typ.t =
if Typ.Name.Cpp.is_class sil_typename then Annot.Class.cpp
else Annot.Item.empty (* No annotations for structs *) in
if is_complete_definition then (
CAst_utils.update_sil_types_map type_ptr sil_type;
CAst_utils.update_sil_types_map type_ptr sil_desc;
let non_statics = get_struct_fields tenv definition_decl in
let fields = CGeneral_utils.append_no_duplicates_fields non_statics extra_fields in
let statics = [] in (* Note: We treat static field same as global variables *)
@ -187,14 +187,14 @@ and get_record_struct_type tenv definition_decl : Typ.t =
let specialization = get_template_specialization tenv definition_decl in
Tenv.mk_struct tenv ~fields ~statics ~methods ~supers ~annots ~specialization
sil_typename |> ignore;
CAst_utils.update_sil_types_map type_ptr sil_type;
sil_type
CAst_utils.update_sil_types_map type_ptr sil_desc;
sil_desc
) else (
(* There is no definition for that struct in whole translation unit.
Put empty struct into tenv to prevent backend problems *)
ignore (Tenv.mk_struct tenv ~fields:extra_fields sil_typename);
CAst_utils.update_sil_types_map type_ptr sil_type;
sil_type))
CAst_utils.update_sil_types_map type_ptr sil_desc;
sil_desc))
| _ -> assert false
and add_types_from_decl_to_tenv tenv decl =

@ -13,7 +13,7 @@ open! IStd
val get_record_typename : ?tenv:Tenv.t -> Clang_ast_t.decl -> Typ.Name.t
val add_types_from_decl_to_tenv : Tenv.t -> Clang_ast_t.decl -> Typ.t
val add_types_from_decl_to_tenv : Tenv.t -> Clang_ast_t.decl -> Typ.desc
(* Adds the predefined types objc_class which is a struct, *)
(* and Class, which is a pointer to objc_class. *)

@ -30,7 +30,7 @@ val get_decl_opt_with_decl_ref : Clang_ast_t.decl_ref option -> Clang_ast_t.decl
val get_property_of_ivar : Clang_ast_t.pointer -> Clang_ast_t.decl option
val update_sil_types_map : Clang_ast_t.type_ptr -> Typ.t -> unit
val update_sil_types_map : Clang_ast_t.type_ptr -> Typ.desc -> unit
val update_enum_map : Clang_ast_t.pointer -> Exp.t -> unit

@ -44,8 +44,8 @@ let enum_decl decl =
match decl with
| EnumDecl (_, _, _, type_ptr, decl_list, _, _) ->
add_enum_constants_to_map (List.rev decl_list);
let sil_type = Typ.mk (Typ.Tint Typ.IInt) in
CAst_utils.update_sil_types_map type_ptr sil_type;
sil_type
let sil_desc = Typ.Tint Typ.IInt in
CAst_utils.update_sil_types_map type_ptr sil_desc;
sil_desc
| _ -> assert false

@ -12,4 +12,4 @@ open! IStd
(** Translate an enumeration declaration by adding it to the tenv and *)
(** translating the code and adding it to a fake procdesc *)
val enum_decl : Clang_ast_t.decl -> Typ.t
val enum_decl : Clang_ast_t.decl -> Typ.desc

@ -106,6 +106,6 @@ val pointer_type_index : Clang_ast_t.c_type Clang_ast_main.PointerMap.t ref
(** Map from type pointers (clang pointers and types created later by frontend) to sil types
Populated during frontend execution when new type is found *)
val sil_types_map : (Typ.t Clang_ast_extend.TypePointerMap.t) ref
val sil_types_map : (Typ.desc Clang_ast_extend.TypePointerMap.t) ref
val reset_global_state : unit -> unit

@ -17,40 +17,40 @@ let get_builtin_objc_typename builtin_type =
let get_builtin_objc_type builtin_type =
let typ = Typ.mk (Tstruct (get_builtin_objc_typename builtin_type)) in
match builtin_type with
| `ObjCId -> typ
| `ObjCClass -> Typ.mk (Tptr (typ, Typ.Pk_pointer))
| `ObjCId -> typ.Typ.desc
| `ObjCClass -> Typ.Tptr (typ, Typ.Pk_pointer)
let sil_type_of_builtin_type_kind builtin_type_kind =
let type_desc_of_builtin_type_kind builtin_type_kind =
match builtin_type_kind with
| `Void -> Typ.mk Tvoid
| `Bool -> Typ.mk (Tint IBool)
| `Char_U -> Typ.mk (Tint IUChar)
| `UChar -> Typ.mk (Tint IUChar)
| `WChar_U -> Typ.mk (Tint IUChar)
| `Char_S -> Typ.mk (Tint IChar)
| `SChar -> Typ.mk (Tint ISChar)
| `Void -> Typ.Tvoid
| `Bool -> Typ.Tint IBool
| `Char_U -> Typ.Tint IUChar
| `UChar -> Typ.Tint IUChar
| `WChar_U -> Typ.Tint IUChar
| `Char_S -> Typ.Tint IChar
| `SChar -> Typ.Tint ISChar
| `WChar_S
| `Char16
| `Char32 -> Typ.mk (Tint IChar)
| `Char32 -> Typ.Tint IChar
| `UShort
| `Short -> Typ.mk (Tint IShort)
| `Short -> Typ.Tint IShort
| `UInt
| `UInt128 -> Typ.mk (Tint IUInt)
| `ULong -> Typ.mk (Tint IULong)
| `ULongLong -> Typ.mk (Tint IULongLong)
| `UInt128 -> Typ.Tint IUInt
| `ULong -> Typ.Tint IULong
| `ULongLong -> Typ.Tint IULongLong
| `Int
| `Int128 -> Typ.mk (Tint IInt)
| `Long -> Typ.mk (Tint ILong)
| `LongLong -> Typ.mk (Tint ILongLong)
| `Half -> Typ.mk (Tint IShort) (*?*)
| `Float -> Typ.mk (Tfloat FFloat)
| `Double -> Typ.mk (Tfloat FDouble)
| `LongDouble -> Typ.mk (Tfloat FLongDouble)
| `NullPtr -> Typ.mk (Tint IInt)
| `Int128 -> Typ.Tint IInt
| `Long -> Typ.Tint ILong
| `LongLong -> Typ.Tint ILongLong
| `Half -> Typ.Tint IShort (*?*)
| `Float -> Typ.Tfloat FFloat
| `Double -> Typ.Tfloat FDouble
| `LongDouble -> Typ.Tfloat FLongDouble
| `NullPtr -> Typ.Tint IInt
| `ObjCId -> get_builtin_objc_type `ObjCId
| `ObjCClass -> get_builtin_objc_type `ObjCClass
| _ -> Typ.mk Tvoid
| _ -> Typ.Tvoid
let pointer_attribute_of_objc_attribute attr_info =
match attr_info.Clang_ast_t.ati_lifetime with
@ -62,35 +62,36 @@ let pointer_attribute_of_objc_attribute attr_info =
let rec build_array_type translate_decl tenv (qual_type : Clang_ast_t.qual_type) n_opt =
let array_type = qual_type_to_sil_type translate_decl tenv qual_type in
let len = Option.map ~f:(fun n -> IntLit.of_int64 (Int64.of_int n)) n_opt in
Typ.mk (Tarray (array_type, len))
Typ.Tarray (array_type, len)
and sil_type_of_attr_type translate_decl tenv type_info attr_info =
and type_desc_of_attr_type translate_decl tenv type_info attr_info =
match type_info.Clang_ast_t.ti_desugared_type with
| Some type_ptr ->
(match CAst_utils.get_type type_ptr with
| Some Clang_ast_t.ObjCObjectPointerType (_, qual_type) ->
let typ = qual_type_to_sil_type translate_decl tenv qual_type in
Typ.mk (Tptr (typ, pointer_attribute_of_objc_attribute attr_info))
| _ -> type_ptr_to_sil_type translate_decl tenv type_ptr)
| None -> Typ.mk Tvoid
Typ.Tptr (typ, pointer_attribute_of_objc_attribute attr_info)
| _ -> type_ptr_to_type_desc translate_decl tenv type_ptr)
| None -> Typ.Tvoid
and sil_type_of_c_type translate_decl tenv c_type : Typ.t =
and type_desc_of_c_type translate_decl tenv c_type : Typ.desc =
let open Clang_ast_t in
match c_type with
| NoneType _ -> Typ.mk Tvoid
| NoneType _ -> Tvoid
| BuiltinType (_, builtin_type_kind) ->
sil_type_of_builtin_type_kind builtin_type_kind
type_desc_of_builtin_type_kind builtin_type_kind
| PointerType (_, qual_type)
| ObjCObjectPointerType (_, qual_type) ->
let typ = qual_type_to_sil_type translate_decl tenv qual_type in
if Typ.equal typ (get_builtin_objc_type `ObjCClass) then
typ
else Typ.mk (Tptr (typ, Typ.Pk_pointer))
let desc = typ.Typ.desc in
if Typ.equal_desc desc (get_builtin_objc_type `ObjCClass) then
desc
else Typ.Tptr (typ, Typ.Pk_pointer)
| ObjCObjectType (_, objc_object_type_info) ->
type_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type
type_ptr_to_type_desc translate_decl tenv objc_object_type_info.Clang_ast_t.base_type
| BlockPointerType (_, qual_type) ->
let typ = qual_type_to_sil_type translate_decl tenv qual_type in
Typ.mk (Tptr (typ, Typ.Pk_pointer))
Typ.Tptr (typ, Typ.Pk_pointer)
| IncompleteArrayType (_, qual_type)
| DependentSizedArrayType (_, qual_type)
| VariableArrayType (_, qual_type) ->
@ -99,33 +100,33 @@ and sil_type_of_c_type translate_decl tenv c_type : Typ.t =
build_array_type translate_decl tenv qual_type (Some n)
| FunctionProtoType _
| FunctionNoProtoType _ ->
Typ.mk (Tfun false)
Typ.Tfun false
| ParenType (_, qual_type) ->
qual_type_to_sil_type translate_decl tenv qual_type
(qual_type_to_sil_type translate_decl tenv qual_type).Typ.desc
| DecayedType (_, qual_type) ->
qual_type_to_sil_type translate_decl tenv qual_type
(qual_type_to_sil_type translate_decl tenv qual_type).Typ.desc
| RecordType (_, pointer)
| EnumType (_, pointer) ->
decl_ptr_to_sil_type translate_decl tenv pointer
decl_ptr_to_type_desc translate_decl tenv pointer
| ElaboratedType (type_info) ->
(match type_info.Clang_ast_t.ti_desugared_type with (* TODO desugar to qualtype *)
Some type_ptr -> type_ptr_to_sil_type translate_decl tenv type_ptr
| None -> Typ.mk Tvoid)
Some type_ptr -> type_ptr_to_type_desc translate_decl tenv type_ptr
| None -> Typ.Tvoid)
| ObjCInterfaceType (_, pointer) ->
decl_ptr_to_sil_type translate_decl tenv pointer
decl_ptr_to_type_desc translate_decl tenv pointer
| RValueReferenceType (_, qual_type)
| LValueReferenceType (_, qual_type) ->
let typ = qual_type_to_sil_type translate_decl tenv qual_type in
Typ.mk (Tptr (typ, Typ.Pk_reference))
Typ.Tptr (typ, Typ.Pk_reference)
| AttributedType (type_info, attr_info) -> (* TODO desugar to qualtyp *)
sil_type_of_attr_type translate_decl tenv type_info attr_info
type_desc_of_attr_type translate_decl tenv type_info attr_info
| _ -> (* TypedefType, etc *)
let type_info = Clang_ast_proj.get_type_tuple c_type in
match type_info.Clang_ast_t.ti_desugared_type with (* TODO desugar typedeftype to qualtype *)
| Some typ -> type_ptr_to_sil_type translate_decl tenv typ
| None -> Typ.mk Tvoid
| Some typ -> type_ptr_to_type_desc translate_decl tenv typ
| None -> Typ.Tvoid
and decl_ptr_to_sil_type translate_decl tenv decl_ptr =
and decl_ptr_to_type_desc translate_decl tenv decl_ptr : Typ.desc =
let open Clang_ast_t in
let typ = Clang_ast_extend.DeclPtr decl_ptr in
try Clang_ast_extend.TypePointerMap.find typ !CFrontend_config.sil_types_map
@ -143,38 +144,40 @@ and decl_ptr_to_sil_type translate_decl tenv decl_ptr =
| Some _ ->
Logging.err_debug "Warning: Wrong decl found for pointer %s "
(Clang_ast_j.string_of_pointer decl_ptr);
Typ.mk Tvoid
Typ.Tvoid
| None ->
Logging.err_debug "Warning: Decl pointer %s not found."
(Clang_ast_j.string_of_pointer decl_ptr);
Typ.mk Tvoid
Typ.Tvoid
and clang_type_ptr_to_sil_type translate_decl tenv type_ptr =
and clang_type_ptr_to_type_desc translate_decl tenv type_ptr =
try
Clang_ast_extend.TypePointerMap.find type_ptr !CFrontend_config.sil_types_map
with Not_found ->
(match CAst_utils.get_type type_ptr with
| Some c_type ->
let sil_type = sil_type_of_c_type translate_decl tenv c_type in
CAst_utils.update_sil_types_map type_ptr sil_type;
sil_type
| _ -> Typ.mk Tvoid)
let type_desc = type_desc_of_c_type translate_decl tenv c_type in
CAst_utils.update_sil_types_map type_ptr type_desc;
type_desc
| _ -> Typ.Tvoid)
and type_ptr_to_sil_type translate_decl tenv type_ptr =
and type_ptr_to_type_desc translate_decl tenv type_ptr : Typ.desc =
match type_ptr with
| Clang_ast_types.TypePtr.Ptr _ -> clang_type_ptr_to_sil_type translate_decl tenv type_ptr
| Clang_ast_extend.Builtin kind -> sil_type_of_builtin_type_kind kind
| Clang_ast_types.TypePtr.Ptr _ -> clang_type_ptr_to_type_desc translate_decl tenv type_ptr
| Clang_ast_extend.Builtin kind -> type_desc_of_builtin_type_kind kind
| Clang_ast_extend.PointerOf typ ->
let sil_typ = qual_type_to_sil_type translate_decl tenv typ in
Typ.mk (Tptr (sil_typ, Pk_pointer))
Typ.Tptr (sil_typ, Pk_pointer)
| Clang_ast_extend.ReferenceOf typ ->
let sil_typ = qual_type_to_sil_type translate_decl tenv typ in
Typ.mk (Tptr (sil_typ, Pk_reference))
Typ.Tptr (sil_typ, Pk_reference)
| Clang_ast_extend.ClassType typename ->
Typ.mk (Tstruct typename)
| Clang_ast_extend.DeclPtr ptr -> decl_ptr_to_sil_type translate_decl tenv ptr
| Clang_ast_extend.ErrorType -> Typ.mk Tvoid
Typ.Tstruct typename
| Clang_ast_extend.DeclPtr ptr -> decl_ptr_to_type_desc translate_decl tenv ptr
| Clang_ast_extend.ErrorType -> Typ.Tvoid
| _ -> raise (invalid_arg "unknown variant for type_ptr")
and qual_type_to_sil_type translate_decl tenv qual_type =
type_ptr_to_sil_type translate_decl tenv qual_type.Clang_ast_t.qt_type_ptr (* FIXME *)
let desc = type_ptr_to_type_desc translate_decl tenv qual_type.Clang_ast_t.qt_type_ptr in
let quals = Typ.mk_type_quals ~is_const:qual_type.Clang_ast_t.qt_is_const () in
Typ.mk ~quals desc

@ -11,12 +11,5 @@ open! IStd
val get_builtin_objc_typename : [< `ObjCClass | `ObjCId ] -> Typ.Name.t
val get_builtin_objc_type : [< `ObjCClass | `ObjCId ] -> Typ.t
val sil_type_of_builtin_type_kind : Clang_ast_t.builtin_type_kind -> Typ.t
val type_ptr_to_sil_type : (Tenv.t -> Clang_ast_t.decl -> Typ.t) ->
Tenv.t -> Clang_ast_t.type_ptr -> Typ.t
val qual_type_to_sil_type : (Tenv.t -> Clang_ast_t.decl -> Typ.t) ->
val qual_type_to_sil_type : (Tenv.t -> Clang_ast_t.decl -> Typ.desc) ->
Tenv.t -> Clang_ast_t.qual_type -> Typ.t

@ -68,9 +68,9 @@ let get_base_class_name_from_category decl =
let process_category qual_type_to_sil_type tenv class_name decl_info decl_list =
let decl_fields = CField_decl.get_fields qual_type_to_sil_type tenv decl_list in
let class_tn_name = Typ.Name.Objc.from_qual_name class_name in
let class_tn_type = Typ.mk (Typ.Tstruct class_tn_name) in
let class_tn_desc = Typ.Tstruct class_tn_name in
let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in
CAst_utils.update_sil_types_map decl_key class_tn_type;
CAst_utils.update_sil_types_map decl_key class_tn_desc;
(match Tenv.lookup tenv class_tn_name with
| Some ({ fields } as struct_typ) ->
let new_fields = CGeneral_utils.append_no_duplicates_fields decl_fields fields in
@ -79,7 +79,7 @@ let process_category qual_type_to_sil_type tenv class_name decl_info decl_list =
~default:struct_typ ~fields:new_fields ~statics:[] ~methods:[] class_tn_name );
Logging.out_debug " Updating info for class '%a' in tenv\n" QualifiedCppName.pp class_name
| _ -> ());
class_tn_type
class_tn_desc
let category_decl qual_type_to_sil_type tenv decl =
let open Clang_ast_t in

@ -12,9 +12,9 @@ open! IStd
(** In this module an ObjC category declaration or implementation is processed. The category *)
(** is saved in the tenv as a struct with the corresponding fields and methods , and the class it belongs to *)
val category_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.t
val category_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc
val category_impl_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.t
val category_impl_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc
val noname_category : string -> string

@ -78,9 +78,9 @@ let add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list o
let class_name = CAst_utils.get_qualified_name name_info in
Logging.out_debug "ADDING: ObjCInterfaceDecl for '%a'\n" QualifiedCppName.pp class_name;
let interface_name = Typ.Name.Objc.from_qual_name class_name in
let interface_type = Typ.mk (Tstruct interface_name) in
let interface_desc = Typ.Tstruct interface_name in
let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in
CAst_utils.update_sil_types_map decl_key interface_type;
CAst_utils.update_sil_types_map decl_key interface_desc;
let decl_supers, decl_fields =
create_supers_fields qual_type_to_sil_type tenv decl_list
ocidi.Clang_ast_t.otdi_super
@ -114,7 +114,7 @@ let add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list o
Logging.out_debug " >>>OK. Found typ='%a'\n"
(Typ.Struct.pp Pp.text interface_name) st
| None -> Logging.out_debug " >>>NOT Found!!\n");
interface_type
interface_desc
(* Interface_type_info has the name of instance variables and the name of methods. *)
let interface_declaration qual_type_to_sil_type tenv decl =
@ -144,7 +144,7 @@ let interface_impl_declaration qual_type_to_sil_type tenv decl =
CField_decl.add_missing_fields tenv class_name fields;
let class_tn_name = Typ.Name.Objc.from_qual_name class_name in
let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in
let class_typ = Typ.mk (Tstruct class_tn_name) in
CAst_utils.update_sil_types_map decl_key class_typ;
class_typ
let class_desc = Typ.Tstruct class_tn_name in
CAst_utils.update_sil_types_map decl_key class_desc;
class_desc
| _ -> assert false

@ -13,9 +13,9 @@ open! IStd
struct with the corresponding fields, potential superclass and list of defined methods *)
val interface_declaration : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl ->
Typ.t
Typ.desc
val interface_impl_declaration : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl ->
Typ.t
Typ.desc
val is_pointer_to_objc_class : Typ.t -> bool

@ -26,12 +26,12 @@ let protocol_decl qual_type_to_sil_type tenv decl =
(* It may turn out that we need a more specific treatment for protocols*)
Logging.out_debug "ADDING: ObjCProtocolDecl for '%a'\n" QualifiedCppName.pp name;
let protocol_name = Typ.Name.Objc.protocol_from_qual_name name in
let protocol_type = Typ.mk (Tstruct protocol_name) in
let protocol_desc = Typ.Tstruct protocol_name in
let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in
CAst_utils.update_sil_types_map decl_key protocol_type;
CAst_utils.update_sil_types_map decl_key protocol_desc;
ignore( Tenv.mk_struct tenv ~methods:[] protocol_name );
add_protocol_super qual_type_to_sil_type tenv obj_c_protocol_decl_info;
protocol_type
protocol_desc
| _ -> assert false
let is_protocol decl =

@ -12,6 +12,6 @@ open! IStd
(** In this module an ObjC protocol declaration or implementation is processed. The protocol *)
(** is saved in the tenv as a struct with the corresponding methods *)
val protocol_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.t
val protocol_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc
val is_protocol : Clang_ast_t.decl -> bool

@ -50,6 +50,7 @@ SOURCES = \
shared/templates/function.cpp \
shared/templates/function_pack.cpp \
shared/templates/method.cpp \
shared/types/const.cpp \
shared/types/inheritance_casts.cpp \
shared/types/inheritance_field.cpp \
shared/types/operator_overload.cpp \

@ -125,6 +125,8 @@ codetoanalyze/cpp/errors/subtyping/dynamic_cast.cpp, dynamic__cast::wrongPointer
codetoanalyze/cpp/errors/subtyping/dynamic_cast.cpp, dynamic__cast::wrongPointerCast, 6, DIVIDE_BY_ZERO, [start of procedure dynamic__cast::wrongPointerCast(),start of procedure Base,return from a call to dynamic__cast::Base_Base,Condition is false]
codetoanalyze/cpp/errors/subtyping/dynamic_cast.cpp, dynamic__cast::wrongReferenceCast, 3, CLASS_CAST_EXCEPTION, [start of procedure dynamic__cast::wrongReferenceCast(),start of procedure Base,return from a call to dynamic__cast::Base_Base]
codetoanalyze/cpp/errors/subtyping/dynamic_cast.cpp, dynamic__cast::wrongReferenceCastNotAssigned, 3, CLASS_CAST_EXCEPTION, [start of procedure dynamic__cast::wrongReferenceCastNotAssigned(),start of procedure Base,return from a call to dynamic__cast::Base_Base]
codetoanalyze/cpp/errors/subtyping/implicit_cast_with_const.cpp, implicit_cast_with_const::BaseDerefNPE, 2, NULL_DEREFERENCE, [start of procedure implicit_cast_with_const::BaseDerefNPE(),start of procedure Base,return from a call to implicit_cast_with_const::Base_Base,start of procedure implicit_cast_with_const::deref()]
codetoanalyze/cpp/errors/subtyping/implicit_cast_with_const.cpp, implicit_cast_with_const::DerivedDerefNPE, 2, NULL_DEREFERENCE, [start of procedure implicit_cast_with_const::DerivedDerefNPE(),start of procedure Derived,start of procedure Base,return from a call to implicit_cast_with_const::Base_Base,return from a call to implicit_cast_with_const::Derived_Derived,start of procedure implicit_cast_with_const::deref()]
codetoanalyze/cpp/errors/subtyping/subtyping_check.cpp, B_setFG, 4, DIVIDE_BY_ZERO, [start of procedure setFG,start of procedure setF,return from a call to A_setF,Condition is true]
codetoanalyze/cpp/errors/vector/access_field_later.cpp, getIntPtr, 1, RETURN_VALUE_IGNORED, [start of procedure getIntPtr()]
codetoanalyze/cpp/errors/vector/access_field_later.cpp, getIntPtr, 2, EMPTY_VECTOR_ACCESS, [start of procedure getIntPtr()]
@ -277,6 +279,9 @@ codetoanalyze/cpp/shared/templates/function_pack.cpp, div0_3args4, 0, DIVIDE_BY_
codetoanalyze/cpp/shared/templates/method.cpp, method::div0_getter, 3, DIVIDE_BY_ZERO, [start of procedure method::div0_getter(),start of procedure X2,return from a call to method::X2_X2,start of procedure Getter,return from a call to method::Getter_Getter,start of procedure get<method::X2>,start of procedure get,return from a call to method::X2_get,return from a call to method::Getter_get<method::X2>]
codetoanalyze/cpp/shared/templates/method.cpp, method::div0_getter_templ, 4, DIVIDE_BY_ZERO, [start of procedure method::div0_getter_templ(),start of procedure X2,return from a call to method::X2_X2,start of procedure X3,return from a call to method::X3_X3,start of procedure GetterTempl,return from a call to method::GetterTempl<method::X3>_GetterTempl,start of procedure get<method::X2>,start of procedure get,return from a call to method::X3_get,start of procedure get,return from a call to method::X2_get,return from a call to method::GetterTempl<method::X3>_get<method::X2>]
codetoanalyze/cpp/shared/templates/method.cpp, method::div0_getter_templ2, 4, DIVIDE_BY_ZERO, [start of procedure method::div0_getter_templ2(),start of procedure X2,return from a call to method::X2_X2,start of procedure X2,return from a call to method::X2_X2,start of procedure GetterTempl,return from a call to method::GetterTempl<method::X2>_GetterTempl,start of procedure get<method::X2>,start of procedure get,return from a call to method::X2_get,start of procedure get,return from a call to method::X2_get,return from a call to method::GetterTempl<method::X2>_get<method::X2>]
codetoanalyze/cpp/shared/types/const.cpp, call_const_params_with_pointer1, 2, NULL_DEREFERENCE, [start of procedure call_const_params_with_pointer1(),start of procedure const_in_param1()]
codetoanalyze/cpp/shared/types/const.cpp, call_const_params_with_pointer2, 2, NULL_DEREFERENCE, [start of procedure call_const_params_with_pointer2(),start of procedure const_in_param2()]
codetoanalyze/cpp/shared/types/const.cpp, call_const_params_with_pointer3, 2, NULL_DEREFERENCE, [start of procedure call_const_params_with_pointer3(),start of procedure const_in_param2()]
codetoanalyze/cpp/shared/types/inheritance_casts.cpp, inheritance_casts::div0_A, 0, DIVIDE_BY_ZERO, [start of procedure inheritance_casts::div0_A(),start of procedure inheritance_casts::getA(),start of procedure A,return from a call to inheritance_casts::A_A,start of procedure A,return from a call to inheritance_casts::A_A,return from a call to inheritance_casts::getA,start of procedure inheritance_casts::div()]
codetoanalyze/cpp/shared/types/inheritance_casts.cpp, inheritance_casts::div0_B, 0, DIVIDE_BY_ZERO, [start of procedure inheritance_casts::div0_B(),start of procedure inheritance_casts::getB(),start of procedure B,start of procedure A,return from a call to inheritance_casts::A_A,return from a call to inheritance_casts::B_B,start of procedure B,start of procedure A,return from a call to inheritance_casts::A_A,return from a call to inheritance_casts::B_B,return from a call to inheritance_casts::getB,start of procedure inheritance_casts::div()]
codetoanalyze/cpp/shared/types/inheritance_field.cpp, div0_b1, 2, DIVIDE_BY_ZERO, [start of procedure div0_b1()]

@ -0,0 +1,35 @@
/*
* Copyright (c) 2017 - 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.
*/
namespace implicit_cast_with_const {
struct Base {
int* f{nullptr};
};
struct Derived : public Base {};
int deref(const Base& b) { return *b.f; }
int BaseDerefNPE() {
Base b;
return deref(b);
}
int DerivedDerefNPE() {
Derived d;
return deref(d);
}
int DerivedDerefNoNpe() {
Derived d;
int x;
d.f = &x;
return deref(d);
}
}

@ -0,0 +1,36 @@
/*
* Copyright (c) 2017 - 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.
*/
int const_in_param1(int const* p) { return *p; }
int const_in_param2(int const* const p) { return *p; }
int call_const_params_with_address() {
int x = 1;
const_in_param1(&x);
const_in_param2(&x);
const int cx = 0;
const_in_param1(&cx);
const_in_param2(&cx);
}
int call_const_params_with_pointer1() {
int* p = nullptr;
const_in_param1(p);
}
int call_const_params_with_pointer2() {
int* p = nullptr;
const_in_param2(p);
}
int call_const_params_with_pointer3() {
int* const cp = nullptr;
const_in_param2(cp);
}

@ -0,0 +1,101 @@
/* @generated */
digraph iCFG {
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_1" [label="1: Start call_const_params_with_address\nFormals: \nLocals: cx:int x:int \n DECLARE_LOCALS(&return,&cx,&x); [line 13]\n " color=yellow style=filled]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_1" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_8" ;
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_2" [label="2: Exit call_const_params_with_address \n " color=yellow style=filled]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_3" [label="3: Call _fun_const_in_param2 \n n$0=_fun_const_in_param2(&cx:int*) [line 21]\n " shape="box"]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_3" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_2" ;
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_4" [label="4: Call _fun_const_in_param1 \n n$1=_fun_const_in_param1(&cx:int*) [line 20]\n " shape="box"]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_4" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_3" ;
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_5" [label="5: DeclStmt \n *&cx:int=0 [line 18]\n " shape="box"]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_5" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_4" ;
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_6" [label="6: Call _fun_const_in_param2 \n n$2=_fun_const_in_param2(&x:int*) [line 16]\n " shape="box"]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_6" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_5" ;
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_7" [label="7: Call _fun_const_in_param1 \n n$3=_fun_const_in_param1(&x:int*) [line 15]\n " shape="box"]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_7" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_6" ;
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_8" [label="8: DeclStmt \n *&x:int=1 [line 14]\n " shape="box"]
"call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_8" -> "call_const_params_with_address#_Z30call_const_params_with_addressv.e754c92d7d89808473eac017465662b5_7" ;
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_1" [label="1: Start call_const_params_with_pointer1\nFormals: \nLocals: p:int* \n DECLARE_LOCALS(&return,&p); [line 24]\n " color=yellow style=filled]
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_1" -> "call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_4" ;
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_2" [label="2: Exit call_const_params_with_pointer1 \n " color=yellow style=filled]
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_3" [label="3: Call _fun_const_in_param1 \n n$0=*&p:int* [line 26]\n n$1=_fun_const_in_param1(n$0:int*) [line 26]\n " shape="box"]
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_3" -> "call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_2" ;
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_4" [label="4: DeclStmt \n *&p:int*=null [line 25]\n " shape="box"]
"call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_4" -> "call_const_params_with_pointer1#_Z31call_const_params_with_pointer1v.95229883c9127e312980c9ae25c8da43_3" ;
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_1" [label="1: Start call_const_params_with_pointer2\nFormals: \nLocals: p:int* \n DECLARE_LOCALS(&return,&p); [line 28]\n " color=yellow style=filled]
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_1" -> "call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_4" ;
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_2" [label="2: Exit call_const_params_with_pointer2 \n " color=yellow style=filled]
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_3" [label="3: Call _fun_const_in_param2 \n n$0=*&p:int* [line 30]\n n$1=_fun_const_in_param2(n$0:int*) [line 30]\n " shape="box"]
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_3" -> "call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_2" ;
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_4" [label="4: DeclStmt \n *&p:int*=null [line 29]\n " shape="box"]
"call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_4" -> "call_const_params_with_pointer2#_Z31call_const_params_with_pointer2v.d36c25662191fdac9d4028112e2d7d51_3" ;
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_1" [label="1: Start call_const_params_with_pointer3\nFormals: \nLocals: cp:int* \n DECLARE_LOCALS(&return,&cp); [line 33]\n " color=yellow style=filled]
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_1" -> "call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_4" ;
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_2" [label="2: Exit call_const_params_with_pointer3 \n " color=yellow style=filled]
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_3" [label="3: Call _fun_const_in_param2 \n n$0=*&cp:int* [line 35]\n n$1=_fun_const_in_param2(n$0:int*) [line 35]\n " shape="box"]
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_3" -> "call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_2" ;
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_4" [label="4: DeclStmt \n *&cp:int*=null [line 34]\n " shape="box"]
"call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_4" -> "call_const_params_with_pointer3#_Z31call_const_params_with_pointer3v.3e5ec1065082911e42d0566ebc0bf6ed_3" ;
"const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_1" [label="1: Start const_in_param1\nFormals: p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 9]\n " color=yellow style=filled]
"const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_1" -> "const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_3" ;
"const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_2" [label="2: Exit const_in_param1 \n " color=yellow style=filled]
"const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_3" [label="3: Return Stmt \n n$0=*&p:int* [line 9]\n n$1=*n$0:int [line 9]\n *&return:int=n$1 [line 9]\n " shape="box"]
"const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_3" -> "const_in_param1#_Z15const_in_param1PKi.1071f2f253e69ef9bc570605af35bf83_2" ;
"const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_1" [label="1: Start const_in_param2\nFormals: p:int*\nLocals: \n DECLARE_LOCALS(&return); [line 11]\n " color=yellow style=filled]
"const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_1" -> "const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_3" ;
"const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_2" [label="2: Exit const_in_param2 \n " color=yellow style=filled]
"const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_3" [label="3: Return Stmt \n n$0=*&p:int* [line 11]\n n$1=*n$0:int [line 11]\n *&return:int=n$1 [line 11]\n " shape="box"]
"const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_3" -> "const_in_param2#_Z15const_in_param2PKi.659d05c79678837da803a1f8b1bc46c1_2" ;
}
Loading…
Cancel
Save