Create the KAST expression
In this step, we begin finding the building blocks that will form our KAST expression, starting by studying the AST hierarchical tree that Checker Studio creates from our test case code.
Finding the KAST nodes of interest
In the AST tree, we can find the first elements of the expression: the KAST node names, hierarchy information, and operation attributes.
- Open Checker Studio, and paste the test case code into the Source Code pane.
- Click 'x = y' in the first block of code.
Checker Studio highlights the first instance of an
ExprStmt
node in the AST tree. TheExprStmt
node has one child node,BinaryExpr
. These two node names will be the first two elements of our first KAST expression building block://ExprStmt / Expr::BinaryExpr
- Click the '=' sign in the source code expression.
Checker Studio highlights the
BinaryExpr
node and displays the KTC attribute code for the "=" operator in the Attributes pane. This attribute expression completes the first element of the KAST expression://ExprStmt / Expr::BinaryExpr [@Op = KTC_OPCODE_ASSIGN]
The elements of the KAST expression we've created so far can be read as "Find all binary operations whose operation is assign."
- Place the expression in any text file while we continue to develop it.
Defining KAST conditions
The next few elements of the KAST expression provide the conditions we want to apply to the checker's search. Using KAST variables (terms prefixed by "$"), we can define the LHS and RHS of our search expressions:
[$expr1:=Left]
[$expr2:=Right]
In accordance with KAST syntax, the square brackets indicate conditions in the expression.
We also want to specify that we're only looking for variables in this checker, and we can do that using our variables and the KAST built-in functions isConstant, isArray, and isPointer in the following conditions:
[not $expr2.isConstant()]
[not $expr1.isPointer() | not $expr2.isArray()]
Adding these conditions to our KAST expression, we get:
//ExprStmt / Expr::BinaryExpr [@Op = KTC_OPCODE_ASSIGN] [$expr1:= Left] [$expr2:= Right] [not $expr2.isConstant()] [not $expr1.isPointer() | not $expr2.isArray()]
The next step in creating the KAST expression is to add conditions that retrieve the variable size by using two new KAST variables and the built-in function, getTypeSize:
[$size1:=$expr1.getTypeSize()] [$size2:=$expr2.getTypeSize()]
The last step is to add the conditions that compare the variables from each side of the statement to zero and to each other:
[$size1 > 0] [$size2 > 0] [$size1 < $size2]
When we add these conditions, we have the completed KAST expression:
//ExprStmt / Expr::BinaryExpr [@Op = KTC_OPCODE_ASSIGN] [$expr1:= Left] [$expr2:= Right] [not $expr2.isConstant()] [not $expr1.isPointer() | not $expr2.isArray()] [$size1:= $expr1.getTypeSize()] [$size2:= $expr2.getTypeSize()] [$size1 > 0] [$size2 > 0] [$size1 < $size2]
This expression can now be read as "Find all binary operations whose operation is assign, and in which the LHS type size is less than the RHS type size."
Test the expression in Checker Studio
To make sure the checker is working the way you want it to, type or copy the KAST expression into the Pattern pane in Checker Studio, and adjust your KAST expression and test case in Checker Studio as needed.
For more examples of KAST expressions, see C/C++ KAST examples, and for more details of KAST syntax, see C/C++ KAST syntax reference.