From b18de9e6417c60b51d2371c98394f4033d2683e4 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 14 Sep 2023 17:12:58 +0100 Subject: [PATCH] C++: Add a named base case predicate for 'dereferencedByOperation' that can be used in queries. --- .../code/cpp/controlflow/Dereferenced.qll | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Dereferenced.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Dereferenced.qll index a8f14b89159..38300645239 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Dereferenced.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Dereferenced.qll @@ -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 | deref.getAChild() = e and deref = op and not deref.getParent*() instanceof SizeofOperator ) or - exists(CrementOperation crement | dereferencedByOperation(e, op) and crement.getOperand() = e) - or exists(ArrayExpr ae | ( not ae.getParent() instanceof AddressOfExpr and @@ -50,6 +51,24 @@ predicate dereferencedByOperation(Expr op, Expr e) { ) ) 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 | dereferencedByOperation(addof, op) and addof.getOperand() = ae and @@ -74,12 +93,6 @@ predicate dereferencedByOperation(Expr op, Expr e) { e = fc.getArgument(i) and 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) {