Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Klocwork (or other tools) be aware of types, typedefs and #define directives?

I have been looking for tools to help detect errors that prevent a program from running properly as 64-bit code. Most recently, I've been toying with Klocwork and its custom checkers feature, which lets me navigate the source code as a tree using XPath. This is useful as a "smarter" alternative to regular expressions, but I have not been able to make it aware of types.

For example, let's say I'd like to find every instance of a for loop that uses either an int or a long to count. The following code is easy to find.

for (int i = 0; i < 10; i++)
    // ...

Searching for this code is trivial because the variable definition is right inside the loop. However, consider the following example.

int i;
// ...
for (i = 0; i < 10; i++)
    // ...

This is difficult to find because the variable definition is separate from the loop, and the necessary XPath expression would be either unwieldy or bug-prone.

So, can custom Klocwork rules find expressions like this where type-awareness is necessary, including resolving typedef and #define statements? Are there other tools which can do this?

EDIT 1: Consider the following example.

typedef int myint;

void Foo() {
    int i;
    for (i = 0; i < 10; i++) {
        Bar();
    }

    myint j;
    for (j = 0; j < 10; j++) {
        Bar();
    }
}

The solution provided by ahmeddirie finds the first loop because the type of i is explicitly defined as int. The second loop is not found, however, because the typedef has obscured the underlying type. What tools keep track of types in a way that would identify the second loop variable j as indeed being an int?

like image 371
Henry Merriam Avatar asked Jun 22 '11 16:06

Henry Merriam


2 Answers

You can use Clang (http://clang.llvm.org) or even Elsa (https://github.com/dsw/oink-stack/) for generating an AST after a type propagation and templates instantiation. Both are providing a decent C++ API and some means for dumping an AST into a readable text. And both options are free.

like image 64
SK-logic Avatar answered Nov 04 '22 11:11

SK-logic


Not entirely sure if this is what you want, but you can always resolve types quite easily with built-in functions. For example, answering your question (although perhaps not your underlying need):

//ForStmt / Init::ExprStmt / Expr::BinaryExpr [ $type := Left.getTypeName() ] [ $type = 'int' | $type.contains('long') ]

This will find ‘for’ loops that use ‘int’ or ‘long int’ counter types quite handily, and can obviously be applied to any element of an expression-based statement.

Type definitions are amenable to this kind of manipulation, whether programmer-defined or language-defined. Pre-processor definitions, however, will only yield their native language type (i.e. the macro itself isn’t available for manipulation via KAST, only what it expands to).

like image 45
ahmeddirie Avatar answered Nov 04 '22 10:11

ahmeddirie