[IR] add Static_local_var pvar kind and use it in clang

Summary:
Remember which globals are static locals.

It's useful to distinguish those from global variables in objc and in the SIOF
checker. Previously in ObjC we would accomplish that by looking at the name of
the variable, but that wouldn't work reliably in C++. Keep the old method around for
now as the way we deal with static locals in ObjC needs some fixing.

Reviewed By: akotulski

Differential Revision: D4198993

fbshipit-source-id: 357dd11
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 0479720c91
commit 9cc9cc101c

@ -26,7 +26,9 @@ type pvar_kind =
| Abduced_retvar Procname.t Location.t /** synthetic variable to represent return value */
| Abduced_ref_param Procname.t t Location.t
/** synthetic variable to represent param passed by reference */
| Global_var (DB.source_file, bool, bool) /** global variable: translation unit + is it compile constant? + is it POD? */
| Global_var (DB.source_file, bool, bool, bool)
/** global variable: translation unit + is it compile constant? + is it POD? + is it a static
local? */
| Seed_var /** variable used to store the initial value of formal parameters */
[@@deriving compare]
/** Names for program variables. */
@ -64,11 +66,12 @@ let rec _pp f pv => {
} else {
F.fprintf f "%a$%a%a|abducedRefParam" Procname.pp n Location.pp l Mangled.pp name
}
| Global_var (fname, is_const, is_pod) =>
| Global_var (fname, is_const, is_pod, _) =>
F.fprintf
f
"#GB<%a%s%s>$%a"
DB.source_file_pp fname
DB.source_file_pp
fname
(if is_const {"|const"} else {""})
(
if (not is_pod) {
@ -227,6 +230,12 @@ let is_global pv =>
| _ => false
};
let is_static_local pv =>
switch pv.pv_kind {
| Global_var (_, _, _, true) => true
| _ => false
};
/** Check if a pvar is the special "this" var */
let is_this pvar => Mangled.equal (get_name pvar) (Mangled.from_string "this");
@ -296,10 +305,16 @@ let mk_callee (name: Mangled.t) (proc_name: Procname.t) :t => {
/** create a global variable with the given name */
let mk_global is_constexpr::is_constexpr=false is_pod::is_pod=true (name: Mangled.t) fname :t => {
let mk_global
is_constexpr::is_constexpr=false
is_pod::is_pod=true
is_static_local::is_static_local=false
(name: Mangled.t)
fname
:t => {
pv_hash: name_hash name,
pv_name: name,
pv_kind: Global_var (fname, is_constexpr, is_pod)
pv_kind: Global_var (fname, is_constexpr, is_pod, is_static_local)
};
@ -324,19 +339,19 @@ let mk_abduced_ref_param (proc_name: Procname.t) (pv: t) (loc: Location.t) :t =>
let get_source_file pvar =>
switch pvar.pv_kind {
| Global_var (f, _, _) => Some f
| Global_var (f, _, _, _) => Some f
| _ => None
};
let is_compile_constant pvar =>
switch pvar.pv_kind {
| Global_var (_, b, _) => b
| Global_var (_, b, _, _) => b
| _ => false
};
let is_pod pvar =>
switch pvar.pv_kind {
| Global_var (_, _, b) => b
| Global_var (_, _, b, _) => b
| _ => true
};

@ -62,11 +62,15 @@ let is_abduced: t => bool;
let is_callee: t => bool;
/** Check if the pvar is a global var */
/** Check if the pvar is a global var or a static local var */
let is_global: t => bool;
/** Check if the pvar is a local var */
/** Check if the pvar is a static variable declared inside a function */
let is_static_local: t => bool;
/** Check if the pvar is a (non-static) local var */
let is_local: t => bool;
@ -104,7 +108,13 @@ let mk_callee: Mangled.t => Procname.t => t;
/** create a global variable with the given name */
let mk_global: is_constexpr::bool? => is_pod::bool? => Mangled.t => DB.source_file => t;
let mk_global:
is_constexpr::bool? =>
is_pod::bool? =>
is_static_local::bool? =>
Mangled.t =>
DB.source_file =>
t;
/** create a fresh temporary variable local to procedure [pname]. for use in the frontends only! */

@ -30,6 +30,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let get_globals astate loc e =
let is_dangerous_global pv =
Pvar.is_global pv
&& not (Pvar.is_static_local pv)
&& not (Pvar.is_pod pv)
&& not (Pvar.is_compile_constant pv) in
let globals = Exp.get_vars e |> snd |> IList.filter is_dangerous_global in

@ -761,7 +761,9 @@ struct
| Clang_ast_t.ClassTemplateSpecializationDecl(_, _, _, _, _, _, _, {xrdi_is_pod}, _) ->
xrdi_is_pod
| _ -> true) true in
Pvar.mk_global ~is_constexpr ~is_pod (mk_name name_string simple_name) translation_unit
Pvar.mk_global ~is_constexpr ~is_pod
~is_static_local:(var_decl_info.Clang_ast_t.vdi_is_static_local)
(mk_name name_string simple_name) translation_unit
let mk_sil_var trans_unit_ctx named_decl_info decl_info_type_ptr_opt procname outer_procname =
match decl_info_type_ptr_opt with

@ -3,7 +3,6 @@ codetoanalyze/cpp/checkers/siof/siof.cpp, __infer_globals_initializer_another_gl
codetoanalyze/cpp/checkers/siof/siof.cpp, __infer_globals_initializer_another_global_object2, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of another_global_object2,call to access_to_non_pod,access to global_object2]
codetoanalyze/cpp/checkers/siof/siof.cpp, __infer_globals_initializer_another_global_object3, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of another_global_object3,call to access_to_templated_non_pod,access to global_object3]
codetoanalyze/cpp/checkers/siof/siof.cpp, __infer_globals_initializer_initWithGlobal, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of initWithGlobal,call to getGlobalNonPOD,access to global_object2]
codetoanalyze/cpp/checkers/siof/siof.cpp, __infer_globals_initializer_initWithStatic, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of initWithStatic,call to getFunctionStaticNonPOD,access to getFunctionStaticNonPOD_instance]
codetoanalyze/cpp/checkers/siof/siof.cpp, __infer_globals_initializer_pod_accesses_non_pod, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of pod_accesses_non_pod,call to access_to_non_pod,access to global_object2]
codetoanalyze/cpp/checkers/siof/siof_templated.cpp, __infer_globals_initializer_another_templated_global_object, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of another_templated_global_object,call to SomeOtherTemplatedNonPODObject<_Bool>_SomeOtherTemplatedNonPODObject,access to extern_global_object]
codetoanalyze/cpp/checkers/siof/siof_templated.cpp, __infer_globals_initializer_another_templated_global_object2, 0, STATIC_INITIALIZATION_ORDER_FIASCO, [initialization of another_templated_global_object2,call to access_to_non_pod,access to global_object2]

Loading…
Cancel
Save