C++: Add a named base case predicate for 'dereferencedByOperation' that can be used in queries.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-09-14 17:12:58 +01:00
parent ff7ff6dcfa
commit b18de9e641

View File

@@ -26,17 +26,18 @@ predicate callDereferences(FunctionCall fc, int i) {
} }
/** /**
* Holds if evaluation of `op` dereferences `e`. * Holds if evaluation of `op` dereferences `e` directly.
*
* This predicate does not recurse through function calls or arithmetic operations. To find
* such cases, use `dereferencedByOperation`.
*/ */
predicate dereferencedByOperation(Expr op, Expr e) { predicate directDereferencedByOperation(Expr op, Expr e) {
exists(PointerDereferenceExpr deref | exists(PointerDereferenceExpr deref |
deref.getAChild() = e and deref.getAChild() = e and
deref = op and deref = op and
not deref.getParent*() instanceof SizeofOperator not deref.getParent*() instanceof SizeofOperator
) )
or or
exists(CrementOperation crement | dereferencedByOperation(e, op) and crement.getOperand() = e)
or
exists(ArrayExpr ae | exists(ArrayExpr ae |
( (
not ae.getParent() instanceof AddressOfExpr and not ae.getParent() instanceof AddressOfExpr and
@@ -50,6 +51,24 @@ predicate dereferencedByOperation(Expr op, Expr e) {
) )
) )
or or
// ptr->Field
e = op.(FieldAccess).getQualifier() and isClassPointerType(e.getType())
or
// ptr->method()
e = op.(Call).getQualifier() and isClassPointerType(e.getType())
}
/**
* Holds if evaluation of `op` dereferences `e`.
*
* This includes the set of operations identified via `directDereferencedByOperation`, as well
* as calls to function that are known to dereference an argument.
*/
predicate dereferencedByOperation(Expr op, Expr e) {
directDereferencedByOperation(op, e)
or
exists(CrementOperation crement | dereferencedByOperation(e, op) and crement.getOperand() = e)
or
exists(AddressOfExpr addof, ArrayExpr ae | exists(AddressOfExpr addof, ArrayExpr ae |
dereferencedByOperation(addof, op) and dereferencedByOperation(addof, op) and
addof.getOperand() = ae and addof.getOperand() = ae and
@@ -74,12 +93,6 @@ predicate dereferencedByOperation(Expr op, Expr e) {
e = fc.getArgument(i) and e = fc.getArgument(i) and
op = fc op = fc
) )
or
// ptr->Field
e = op.(FieldAccess).getQualifier() and isClassPointerType(e.getType())
or
// ptr->method()
e = op.(Call).getQualifier() and isClassPointerType(e.getType())
} }
private predicate isClassPointerType(Type t) { private predicate isClassPointerType(Type t) {