Module TwoOperands
A module for dealing with pairs of exclusive operands.
For instance, to find cases where one operand is an integer and the other is a constant, you will want to to perform checks on each operand separately and consistently without worrying about order. This module makes this common pattern easy to implement.
This module takes two type parameters:
Operand: the type of the operands (e.g.Expr)HasOperands: a type that has operands of typeOperand(e.g.BinaryExpr)
Typically, this module should be imported for the relevant language, such as qtil.cpp.ast. In
this case, only the HasOperands type parameter is required.
// Using this module:
predicate myBinaryTestNew(BinaryExpr e) {
exists(TwoOperands<BinaryExpr>::Set set |
set.getOperation() = e and
set.someOperand().isInteger() and
set.otherOperand().isConstant()
)
}
// Is roughly equivalent to:
predicate myBinaryTestOld(BinaryExpr e) {
exists(Expr a, Expr b |
e.getAnOperand() = a and
e.getAnOperand() = b and
a != b and
a.isInteger() and
b.isConstant()
)
}
Some caution about using this module: for each use, two Set objects exst. If you do not
properly constrain the usage of someOperand() and otherOperand(), then these members could
hold for different Sets. Therefore, someOperand() and otherOperand() may be the same
operand. This will not happen if the Set is properly constrained across the two member
invocations.
predicate bug(BinaryExpr e) {
// Bad: the two sets are not constrained to the same instance, therefore the operands not
// guaranteed to be different.
TwoOperands<BinaryExpr>::getASet(e).someOperand().isInteger() and
TwoOperands<BinaryExpr>::getASet(e).otherOperand().isConstant()
}
Import path
import qtil.ast.TwoOperandsPredicates
Classes
| Set | A class that represents a pair of operands of the same operation, where the two operands are different. |
Parameters
| Operand | FiniteStringableType | |
| HasOperands | HasOperands |