From a2312462ebce4198179091e481ee45e3890d36ac Mon Sep 17 00:00:00 2001 From: Sungkeun Cho Date: Thu, 1 Nov 2018 02:13:51 -0700 Subject: [PATCH] [inferbo] Use values of global constant variables in C Reviewed By: mbouaziz Differential Revision: D12838577 fbshipit-source-id: 8e7c45596 --- infer/src/IR/Pvar.ml | 2 ++ infer/src/IR/Pvar.mli | 4 ++++ infer/src/bufferoverrun/bufferOverrunChecker.ml | 3 ++- infer/tests/codetoanalyze/c/bufferoverrun/global.c | 12 ++++++++++++ infer/tests/codetoanalyze/c/bufferoverrun/issues.exp | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/infer/src/IR/Pvar.ml b/infer/src/IR/Pvar.ml index 9c6ca87e9..863723fed 100644 --- a/infer/src/IR/Pvar.ml +++ b/infer/src/IR/Pvar.ml @@ -256,6 +256,8 @@ let is_compile_constant pvar = match pvar.pv_kind with Global_var {is_constexpr} -> is_constexpr | _ -> false +let is_ice pvar = match pvar.pv_kind with Global_var {is_ice} -> is_ice | _ -> false + let is_pod pvar = match pvar.pv_kind with Global_var {is_pod} -> is_pod | _ -> true let get_initializer_pname {pv_name; pv_kind} = diff --git a/infer/src/IR/Pvar.mli b/infer/src/IR/Pvar.mli index 452a3c679..fdd04ad8c 100644 --- a/infer/src/IR/Pvar.mli +++ b/infer/src/IR/Pvar.mli @@ -130,6 +130,10 @@ val is_compile_constant : t -> bool (** Is the variable's value a compile-time constant? Always (potentially incorrectly) returns [false] for non-globals. *) +val is_ice : t -> bool +(** Is the variable's type an integral constant expression? Always (potentially incorrectly) returns + [false] for non-globals. *) + val is_pod : t -> bool (** Is the variable's type a "Plain Old Data" type (C++)? Always (potentially incorrectly) returns [true] for non-globals. *) diff --git a/infer/src/bufferoverrun/bufferOverrunChecker.ml b/infer/src/bufferoverrun/bufferOverrunChecker.ml index 7c17de9ac..4321868a4 100644 --- a/infer/src/bufferoverrun/bufferOverrunChecker.ml +++ b/infer/src/bufferoverrun/bufferOverrunChecker.ml @@ -145,7 +145,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct match instr with | Load (id, _, _, _) when Ident.is_none id -> mem - | Load (id, Exp.Lvar pvar, _, location) when Pvar.is_compile_constant pvar -> ( + | Load (id, Exp.Lvar pvar, _, location) when Pvar.is_compile_constant pvar || Pvar.is_ice pvar + -> ( match Pvar.get_initializer_pname pvar with | Some callee_pname -> ( match Ondemand.analyze_proc_name ~caller_pdesc:pdesc callee_pname with diff --git a/infer/tests/codetoanalyze/c/bufferoverrun/global.c b/infer/tests/codetoanalyze/c/bufferoverrun/global.c index d4edb0d4d..7eb7b97ba 100644 --- a/infer/tests/codetoanalyze/c/bufferoverrun/global.c +++ b/infer/tests/codetoanalyze/c/bufferoverrun/global.c @@ -21,3 +21,15 @@ void compare_global_const_enum_bad_FN() { if (global_const < 10) arr[10] = 1; } + +const int global_const_ten = 10; + +void use_global_const_ten_Good() { + char arr[20]; + arr[global_const_ten] = 0; +} + +void use_global_const_ten_Bad() { + char arr[5]; + arr[global_const_ten] = 0; +} diff --git a/infer/tests/codetoanalyze/c/bufferoverrun/issues.exp b/infer/tests/codetoanalyze/c/bufferoverrun/issues.exp index 3f4a24ea3..b21746e62 100644 --- a/infer/tests/codetoanalyze/c/bufferoverrun/issues.exp +++ b/infer/tests/codetoanalyze/c/bufferoverrun/issues.exp @@ -64,6 +64,7 @@ codetoanalyze/c/bufferoverrun/get_field.c, call_get_field_cond_Bad, 4, BUFFER_OV codetoanalyze/c/bufferoverrun/global.c, compare_global_const_enum_bad_FN, 2, CONDITION_ALWAYS_FALSE, no_bucket, WARNING, [] codetoanalyze/c/bufferoverrun/global.c, compare_global_const_enum_bad_FN, 2, CONDITION_ALWAYS_TRUE, no_bucket, WARNING, [] codetoanalyze/c/bufferoverrun/global.c, compare_global_variable_bad, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [ArrayDeclaration,ArrayAccess: Offset: 10 Size: 10] +codetoanalyze/c/bufferoverrun/global.c, use_global_const_ten_Bad, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [ArrayDeclaration,Assignment,ArrayAccess: Offset: 10 Size: 5] codetoanalyze/c/bufferoverrun/goto_loop.c, goto_infinite_loop, 3, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [Assignment,Binop: ([0, +oo] + 1):signed32] codetoanalyze/c/bufferoverrun/goto_loop.c, goto_infinite_loop, 4, CONDITION_ALWAYS_TRUE, no_bucket, WARNING, [] codetoanalyze/c/bufferoverrun/goto_loop.c, goto_infinite_loop, 10, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [Assignment,Assignment,Binop: ([1, +oo] + 1):signed32]