[DRAFT] [pulse] do not keep the arguments of pure calls alive through their result - #2178
Draft
VladimirMakaev wants to merge 1 commit into
Draft
VladimirMakaev wants to merge 1 commit into
VladimirMakaev wants to merge 1 commit into
Conversation
VladimirMakaev
force-pushed
the
pulse-dead-function-terms
branch
from
October 3, 2026 20:12
e6d31c7 to
391fb3c
Compare
VladimirMakaev
force-pushed
the
pulse-dead-function-terms
branch
from
October 5, 2026 02:40
391fb3c to
a99fb6f
Compare
…esult
Pulse records calls to unknown functions that cannot write through their arguments as `v = f(x)`.
Summaries kept `x` alive through this equality whenever `v` was live, which hid leaks of `x` and
made summaries grow exponentially along trees of such calls.
```c
#include <stdlib.h>
int read_through_const_pointer(const int* p); // unknown
int leak_bad() {
int* p = malloc(sizeof(int));
if (p == NULL) {
return 0;
}
return read_through_const_pointer(p); // Infer missed: memory leak
}
```
Now the result and the other arguments no longer keep a dead argument alive, unless callers can
compute it again, like `g()` in `f(g())`; the equalities that mention it are dropped.
This exposed a bug: inlining the initializer of a global constant argument, as in
`exchange(fd_, kInvalid)`, could overwrite another argument of the call. It no longer does.
Limitations: this applies to all allocations (malloc, `new`, file descriptors, CoreFoundation
objects, C# resources):
- unknown functions that close a descriptor or return their pointer argument now cause leak
reports, e.g. `return my_close(fd);`
- results of calls sharing a dead argument are no longer related.
## Test plan
New leak tests in `c/pulse/memory_leak.c`, `c/pulse/resource_leak.c` and `cpp/pulse/leaks.cpp`,
with `FP_` tests for the limitations, and ground pure call and global constant tests. A depth-16
tree of `combine(f(), f())` calls over a local buffer took 6.7 s and a 14 MB results database
before, 0.1 s and 0.2 MB after. Codetoanalyze tests pass.
VladimirMakaev
force-pushed
the
pulse-dead-function-terms
branch
from
October 5, 2026 06:53
a99fb6f to
199e333
Compare
VladimirMakaev
added a commit
to VladimirMakaev/infer
that referenced
this pull request
Oct 5, 2026
…esult Pulse records calls to unknown functions that cannot write through their arguments as `v = f(x)`. Summaries kept `x` alive through this equality whenever `v` was live, which hid leaks of `x` and made summaries grow exponentially along trees of such calls. Expectation conflicts with earlier frontier commits were resolved automatically in: infer/tests/codetoanalyze/cpp/pulse/issues.exp, infer/tests/codetoanalyze/cpp/pulse/issues.exp-11 Expected test output regenerated for the combination with earlier frontier commits (no new or lost report): infer/tests/codetoanalyze/java/pulse/issues.exp (line numbers only) Upstream-PR: facebook#2178 PR-Head: 199e333 PR-Base: 9cc2641
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pulse records calls to unknown functions that cannot write through their arguments as
v = f(x).Summaries kept
xalive through this equality whenevervwas live, which hid leaks ofxandmade summaries grow exponentially along trees of such calls.
Now the result and the other arguments no longer keep a dead argument alive, unless callers can
compute it again, like
g()inf(g()); the equalities that mention it are dropped.This exposed a bug: inlining the initializer of a global constant argument, as in
exchange(fd_, kInvalid), could overwrite another argument of the call. It no longer does.Limitations: this applies to all allocations (malloc,
new, file descriptors, CoreFoundationobjects, C# resources):
e.g.
return my_close(fd);. On libuv 1.48, this adds 2 PULSE_RESOURCE_LEAK false positives, atsrc/unix/pipe.c:130(uv_pipe_bind2) andsrc/unix/tcp.c:78(new_socket), where a helpercloses the descriptor or keeps it; main already reports 2 of this kind in
new_socket.Test plan
New leak tests in
c/pulse/memory_leak.c,c/pulse/resource_leak.candcpp/pulse/leaks.cpp,with
FP_tests for the limitations, and ground pure call and global constant tests. A depth-16tree of
combine(f(), f())calls over a local buffer took 6.7 s and a 14 MB results databasebefore, 0.1 s and 0.2 MB after. Codetoanalyze tests pass.