[inferbo] Handle field access from global struct arrays

Summary: D25952894 (1bce54aaf3) changes translation of struct assignments. This diff adopts to this change for loads from global struct arrays.

Reviewed By: skcho

Differential Revision: D26398627

fbshipit-source-id: cc1fb47ab
master
Ezgi Çiçek 4 years ago committed by Facebook GitHub Bot
parent 9cdd87b67b
commit a6a279d845

@ -2020,8 +2020,18 @@ module MemReach = struct
let init : get_summary -> OndemandEnv.t -> t = let init : get_summary -> OndemandEnv.t -> t =
fun get_summary oenv -> fun get_summary oenv ->
let find_global_array loc = let find_global_array loc =
Option.bind (Loc.get_global_array_initializer loc) ~f:(fun pname -> let open IOption.Let_syntax in
Option.bind (get_summary pname) ~f:(find_opt loc) ) let* pname = Loc.get_global_array_initializer loc in
let* m = get_summary pname in
match loc with
| BoField.Field {prefix; fn} when Loc.is_global prefix ->
(* This case handles field access of global array:
n$0 = *x[n].field *)
let+ v = find_opt prefix m in
let locs = Val.get_all_locs v |> PowLoc.append_field ~fn in
find_set locs m
| _ ->
find_opt loc m
in in
{ stack_locs= StackLocs.bot { stack_locs= StackLocs.bot
; mem_pure= MemPure.bot ; mem_pure= MemPure.bot

@ -23,3 +23,23 @@ static int StaticGlobal[][3] = {
void access_static_global1_Bad() { int* p = StaticGlobal[10]; } void access_static_global1_Bad() { int* p = StaticGlobal[10]; }
void access_static_global2_Bad() { int a = StaticGlobal[0][10]; } void access_static_global2_Bad() { int a = StaticGlobal[0][10]; }
class Foo {
public:
int p;
Foo(int x) { p = x; }
};
static const Foo ConstantGlobalFoos[] = {{8}};
void access_via_class_field_assignment_constant_global_Bad() {
int a[5];
const Foo foo = ConstantGlobalFoos[0];
a[foo.p] = 3;
}
void access_via_class_field_constant_global_Bad() {
int a[5];
a[ConstantGlobalFoos[0].p] = 3;
}

@ -53,6 +53,8 @@ codetoanalyze/cpp/bufferoverrun/global.cpp, access_constant_global_Bad, 2, BUFFE
codetoanalyze/cpp/bufferoverrun/global.cpp, access_static_global1_Bad, 0, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 10 Size: 5] codetoanalyze/cpp/bufferoverrun/global.cpp, access_static_global1_Bad, 0, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 10 Size: 5]
codetoanalyze/cpp/bufferoverrun/global.cpp, access_static_global2_Bad, 0, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 10 Size: 3] codetoanalyze/cpp/bufferoverrun/global.cpp, access_static_global2_Bad, 0, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Array declaration,Array access: Offset: 10 Size: 3]
codetoanalyze/cpp/bufferoverrun/global.cpp, access_via_assignment_constant_global_Bad, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Array access: Offset: 5 Size: 5] codetoanalyze/cpp/bufferoverrun/global.cpp, access_via_assignment_constant_global_Bad, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Array declaration,Array access: Offset: 5 Size: 5]
codetoanalyze/cpp/bufferoverrun/global.cpp, access_via_class_field_assignment_constant_global_Bad, 3, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Call,Parameter `x`,Assignment,Call,Parameter `__param_0->p`,Assignment,<Length trace>,Array declaration,Array access: Offset: 8 Size: 5]
codetoanalyze/cpp/bufferoverrun/global.cpp, access_via_class_field_constant_global_Bad, 2, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Call,Parameter `x`,Assignment,<Length trace>,Array declaration,Array access: Offset: 8 Size: 5]
codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Set array size,Assignment,Array access: Offset: 5 Size: 5] codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Set array size,Assignment,Array access: Offset: 5 Size: 5]
codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_flexible_array_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Set array size,Array access: Offset: 7 Size: 5] codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_flexible_array_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Length trace>,Set array size,Array access: Offset: 7 Size: 5]
codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_struct1_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Set array size,Assignment,Array access: Offset: 5 Size: 5] codetoanalyze/cpp/bufferoverrun/realloc.cpp, realloc_struct1_Bad, 4, BUFFER_OVERRUN_L1, no_bucket, ERROR, [<Offset trace>,Assignment,<Length trace>,Set array size,Assignment,Array access: Offset: 5 Size: 5]

@ -233,8 +233,8 @@ codetoanalyze/objc/performance/mutable_copy_test.m, MyMutableObj.setMObjects:, 3
codetoanalyze/objc/performance/mutable_copy_test.m, loop_over_mutable_copy_linear, 31 + 3 ⋅ b->_mObjects->elements.length.ub + 3 ⋅ (b->_mObjects->elements.length.ub + 1), OnUIThread:false, [{b->_mObjects->elements.length.ub + 1},Loop,{b->_mObjects->elements.length.ub},Loop] codetoanalyze/objc/performance/mutable_copy_test.m, loop_over_mutable_copy_linear, 31 + 3 ⋅ b->_mObjects->elements.length.ub + 3 ⋅ (b->_mObjects->elements.length.ub + 1), OnUIThread:false, [{b->_mObjects->elements.length.ub + 1},Loop,{b->_mObjects->elements.length.ub},Loop]
codetoanalyze/objc/performance/purity.m, loop, 6006 + 1000 ⋅ |fun_ptr|, OnUIThread:false, [] codetoanalyze/objc/performance/purity.m, loop, 6006 + 1000 ⋅ |fun_ptr|, OnUIThread:false, []
codetoanalyze/objc/performance/struct_test.m, __infer_globals_initializer_mSpecs, 4, OnUIThread:false, [] codetoanalyze/objc/performance/struct_test.m, __infer_globals_initializer_mSpecs, 4, OnUIThread:false, []
codetoanalyze/objc/performance/struct_test.m, const_struct_field_read_constant_FP, 4 + mSpecs.fileName->strlen.ub, OnUIThread:false, [{mSpecs.fileName->strlen.ub},Modeled call to NSString.stringWithUTF8String:] codetoanalyze/objc/performance/struct_test.m, const_struct_field_read_constant, 9, OnUIThread:false, []
codetoanalyze/objc/performance/struct_test.m, loop_array_struct_constant, 9, OnUIThread:false, [] codetoanalyze/objc/performance/struct_test.m, loop_array_struct_constant, 17, OnUIThread:false, []
codetoanalyze/objc/performance/switch_continue.m, test_switch_FN, 600, OnUIThread:false, [] codetoanalyze/objc/performance/switch_continue.m, test_switch_FN, 600, OnUIThread:false, []
codetoanalyze/objc/performance/switch_continue.m, unroll_loop, 15 + (n - 1) + 11 ⋅ (max(1, n)), OnUIThread:false, [{max(1, n)},Loop,{n - 1},Loop] codetoanalyze/objc/performance/switch_continue.m, unroll_loop, 15 + (n - 1) + 11 ⋅ (max(1, n)), OnUIThread:false, [{max(1, n)},Loop,{n - 1},Loop]
codetoanalyze/objc/performance/two_loops_symbolic.m, nop, 1, OnUIThread:false, [] codetoanalyze/objc/performance/two_loops_symbolic.m, nop, 1, OnUIThread:false, []

@ -19,7 +19,7 @@ static const MSpec mSpecs[] = {
{SPEC_FILE_NAME("io")}, {SPEC_FILE_NAME("io")},
}; };
void const_struct_field_read_constant_FP() { void const_struct_field_read_constant() {
MSpec spec = mSpecs[0]; MSpec spec = mSpecs[0];
NSString* fileName = NSString* fileName =
@(spec.fileName); // filename is constant, so this should be O(1) @(spec.fileName); // filename is constant, so this should be O(1)
@ -28,5 +28,6 @@ void const_struct_field_read_constant_FP() {
void loop_array_struct_constant() { void loop_array_struct_constant() {
const MSpec* const endSpec = ((const MSpec*)mSpecs) + ARRAY_COUNT(mSpecs); const MSpec* const endSpec = ((const MSpec*)mSpecs) + ARRAY_COUNT(mSpecs);
for (const MSpec* spec = (const MSpec*)mSpecs; spec < endSpec; spec++) { for (const MSpec* spec = (const MSpec*)mSpecs; spec < endSpec; spec++) {
NSString* fileName = @(spec->fileName);
} }
} }

Loading…
Cancel
Save