Write a CodeQL query that finds coroutine methods that take parameters by reference, where those parameters are used after any co_await suspension point.
import cpp
/**
* Find coroutine functions that take at least one parameter by reference,
* and use that parameter after a co_await suspension point.
*/
from
Function f,
Parameter p,
Expr use,
AwaitExpr await
where
// The function is a coroutine (contains at least one co_await)
exists(AwaitExpr anyAwait | anyAwait.getEnclosingFunction() = f) and
// The parameter is passed by reference (not by value or pointer)
p.getFunction() = f and
p.getType() instanceof ReferenceType and
// There is a use of the parameter after a co_await in the function
use = p.getAnAccess() and
await.getEnclosingFunction() = f and
// The use occurs after the await in the control flow
exists(BasicBlock bb1, BasicBlock bb2 |
await.getBasicBlock() = bb1 and
use.getBasicBlock() = bb2 and
bb1.postdominates(bb2) = false and
bb1.dominates(bb2)
)
select f, p, use, "Parameter $" + p.getName() + " is used after co_await in coroutine " + f.getName()