Summary: When encountering a constant, pulse creates an abstract value (a variable) to represent it, and remembers that it's equal to it. The problem is that pulse doesn't yet know how to deal with the fact that some variables are going to be equal to each other. This hacks around this issue in the case of constants, within the same procedure, by remembering which constants have been assigned to which place-holder variables, and serving those variables again when the same constant is translated again. Limitation: this doesn't work across procedure calls as the "constant maps" are not saved in summaries. Something to look out for: we don't want to make `if (p == NULL)` create a path where `p` is invalid (we only make null invalid when we see an assignment from 0, i.e. `p = NULL;`). Reviewed By: ezgicicek Differential Revision: D21089961 fbshipit-source-id: 5ebb85d0amaster
parent
196043ab61
commit
3220804ddb
@ -1,3 +1,4 @@
|
||||
codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad, 0, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,when calling `create_p` here,allocated by call to `malloc` (modelled),allocation part of the trace ends here,memory becomes unreachable here]
|
||||
codetoanalyze/c/pulse/memory_leak.c, malloc_interproc_no_free_bad2, 4, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc` (modelled),allocation part of the trace ends here,memory becomes unreachable here]
|
||||
codetoanalyze/c/pulse/memory_leak.c, malloc_no_free_bad, 0, PULSE_MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc` (modelled),allocation part of the trace ends here,memory becomes unreachable here]
|
||||
codetoanalyze/c/pulse/nullptr.c, malloc_no_check_bad, 2, NULLPTR_DEREFERENCE, no_bucket, ERROR, [invalidation part of the trace starts here,allocated by call to `malloc` (modelled),is the null pointer,use-after-lifetime part of the trace starts here,allocated by call to `malloc` (modelled),assigned,invalid access occurs here]
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int* malloc_no_check_bad() {
|
||||
int* p = malloc(sizeof(int));
|
||||
*p = 42;
|
||||
return p;
|
||||
}
|
||||
|
||||
void create_null_path_ok(int* p) {
|
||||
if (p) {
|
||||
*p = 32;
|
||||
}
|
||||
}
|
||||
|
||||
void call_create_null_path_then_deref_unconditionally_ok(int* p) {
|
||||
create_null_path_ok(p);
|
||||
*p = 52;
|
||||
}
|
||||
|
||||
void create_null_path2_ok(int* p) {
|
||||
int* q = NULL;
|
||||
if (p) {
|
||||
*p = 32;
|
||||
}
|
||||
// arguably bogus to check p above but not here, but the above could
|
||||
// also be macro-generated code so both reporting and not reporting
|
||||
// are sort of justifiable
|
||||
*p = 52;
|
||||
}
|
||||
|
||||
// combine several of the difficulties above
|
||||
void malloc_then_call_create_null_path_then_deref_unconditionally_ok(int* p) {
|
||||
int* x = malloc(sizeof(int));
|
||||
if (p) {
|
||||
*p = 32;
|
||||
}
|
||||
create_null_path_ok(p);
|
||||
*p = 52;
|
||||
free(x);
|
||||
}
|
Loading…
Reference in new issue