Using the Clang Static Analyzer

In this recipe, you will learn about the static analysis of code, which is carried out by the Clang Static Analyzer. It is built on top of Clang and LLVM. The static analysis engine used by the Clang Static Analyzer is a Clang library, and it has the capability to be reused in different contexts by different clients.

We will take the example of the divide-by-zero defect and show you how the Clang Static Analyzer handles this defect.

Getting ready

You need to build and install LLVM along with Clang.

How to do it…

Perform the following steps:

  1. Create a test file and write the test code in it:
    $ cat sa.c
    int func() {
    int a = 0;
    int b = 1/a;
    return b;
    }
    
  2. Run the Clang Static Analyzer by passing the command-line options shown in the following command, and get the output on the screen:
    $ clang -cc1 -analyze -analyzer-checker=core.DivideZero sa.c
    sa.c:3:10: warning: Division by zero
    int b = 1/a;
            ~^~
    1 warning generated.
    

How it works…

The static analyzer core performs the symbolic execution of the program. The input values are represented by symbolic values. The values of the expressions are calculated by the analyzer using the input symbol and the path. The execution of the code is path-sensitive, and hence every possible path is analyzed.

While executing, the execution traces are represented by an exploded graph. Each node of this ExplodedGraph is called ExplodedNode. It consists of a ProgramState object, which represents the abstract state of the program; and a ProgramPoint object, which represents the corresponding location in the program.

For each type of bug, there is an associated checker. Each of these checkers is linked to the core in a way by which they contribute to the ProgramState construction. Each time the analyzer engine explores a new statement, it notifies each checker registered to listen for that statement, giving it an opportunity to either report a bug or modify the state.

Each checker registers for some events and callbacks such as PreCall (prior to the call of the function), DeadSymbols (when a symbol goes dead), and so on. They are notified in the case of the requested events, and they implement the action to be taken for such events.

In this recipe, we looked at a divide-by-zero checker, which reports when a divide-by-zero condition occurs. The checker, in this case, registers for the PreStmt callback, before a statement gets executed. It then checks the operator of the next statement to be executed, and if it finds a division operator, it looks for a zero value. If it finds such a possible value, it reports a bug.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.26.138