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
?
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With