How does Clang Static Analyzer deal with malloc()?

Hello Arthur,

Did you enable MallocChecker (unix.Malloc)? This is the only checker evaluating malloc() calls.

Hello Arthur,

Did you enable MallocChecker (unix.Malloc)? This is the only checker evaluating malloc() calls.

Good point.

You can try stepping with the debugger in the place where the malloc checker constructs the region:

MallocChecker.cpp:870
   867 const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
   868 DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
   869 .castAs<DefinedSVal>();
-> 870 State = State->BindExpr(CE, C.getLocationContext(), RetVal);
   871
   872 // We expect the malloc functions to return a pointer.
   873 if (!RetVal.getAs<Loc>())

On the other hand, the main reason we are using heap region is to know that two heap regions cannot alias. Is there a reason why you need to have that info?

For *malloc()* problem, I have done some tests with the code below, which
is lightly modified based on the testcase from commit r158136.

int CMPRegionHeapToStack_modified () {

    int x = 0;

    int *x1 = malloc(8);

    int *x2 = &x;

*x2 = 3;

*x1 = 2;

    free(x1);

    return x;

}

When evaluating the write operation in ?**x2 = 3;*?, I could got the
MemRegion of *x*, which is actually the MemRegion referred by *x2*. Then I
tried to get the super region of *x*. Consequently, I got the
*StackLocalsSapaceRegion,
*which conforms to my expectation. However, then I tried to do the same
things on ?**x1 = 2*? and *x1*. Firstly, I got *element{SymRegion{conj_$2{void
*}},0 S32b,int}*, which is the MemRegion referred by *x1* via *malloc()*.
Then I tried to get the super region of *SymRegion{conj_$2{void *}}. *What
I got is *UnkonwnSpaceRegion*. In my expectation, the result should be
*HeapSapceRegion*. In a nutshell, from the result, it seems that Static
Analyzer thought the parent of *SymRegion{conj_$2{void *}}* (referred by
*x1* via *malloc()*) is *UnkonwnSpaceRegion,* rather than* HeapSapceRegion.
*I don?t know why?

For the problem of *isInSystemHeader()* of CallEvent, I did this in the
checkPreCall(). Here is my code.

void MyChecker::checkPreCall(const CallEvent &Call, CheckerContext &C)
const {

       if(Call.isInSystemHeader()) {

       return; /* Ignore the system function calls */

}

/* Here is the code for the function calls not in the system header */

       std::cout << ?Call.isInSystemHeader() is false\n?;

??

}

My test code contains some system function calls, such as *scanf(),
printf(), malloc()* and etc. When evaluating these function calls, the
checkPreCall() did?t return directly. On the contrary, the checker
continued to do the things that for non-system function calls. So it
doesn?t work and confused me. It seems that Static Analyzer cannot tell
whether a function call is in system header rightly with
*isInSystemHeader()*. I did this test on the LLVM/Clang 3.4.2 downloaded
from http://llvm.org/releases/download.html#3.4.2.

My main guess is that you declare the functions in your test (instead of getting declarations from the headers). In that case, the compiler will not recognize them as coming from system headers.
You should use #pragma clang system_header to mark the declarations in your tests; for example, see test/Analysis/Inputs/system-header-simulator-for-malloc.h