About Pointer Escape

// clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
// A value escapes in four possible cases:
// (1) We are binding to something that is not a memory region.
// (2) We are binding to a MemRegion that does not have stack storage.
// (3) We are binding to a top-level parameter region with a non-trivial
//     destructor. We won't see the destructor during analysis, but it's there.
// (4) We are binding to a MemRegion with stack storage that the store
//     does not understand.
ProgramStateRef ExprEngine::processPointerEscapedOnBind()

For item (2), I am trying to figure out why CSA treat MemRegion does not have a stack storage as “escape”?

node_type *p = (node_type *)malloc(sizeof(node_type));
p->value = (int *)malloc(sizeof(int));

For the code above, pointer p->value will be in escaped set due to case (2). If there is a leak by this pointer, it will be a false negtive if it is marked escape.


This algorithm isn’t perfectly precise. In this case, if there’s literally nothing else going on, it’s most likely a false negative (but in this case the leak of p is a true positive). But if p is ever stored anywhere outside the function, before or after the assignment to ->value, it’s becomes a nightmare to prove that it actually leaks. And if it’s not stored anywhere outside the function, then why does the code use a heap allocation in the first place?

In some cases it could be a false positive even when memory is on the stack (say, if the stack address itself escaped outside the function before the assignment, we don’t yet catch that).

So this is mostly about what we can or cannot prove; proving that a non-stack location isn’t accessible by anything else in the program is much harder than proving that a stack location isn’t accessible by anything else in the program, given that a stack location is always short-lived and isn’t initially accessible by anything.