C++: Work around extractor issue CPP-383

This fixes `PointlessComparison.ql` on https://github.com/an-tao/drogon.
The QL is a bit obfuscated because it looks for a pattern that's
impossible according to the dbscheme. There is no accompanying test
because we haven't been able to boil this problem down to a simple test
case. If we could, we'd fix it directly in the extractor instead.
This commit is contained in:
Jonas Jensen 2019-04-25 14:59:01 +02:00
Родитель 3231b60e6b
Коммит 48a3385809
1 изменённых файлов: 34 добавлений и 1 удалений

Просмотреть файл

@ -15,9 +15,42 @@ predicate abortingFunction(Function f) {
not potentiallyReturningFunction(f) not potentiallyReturningFunction(f)
} }
/**
* This relation is the same as the `el instanceof Function`, only obfuscated
* so the optimizer will not understand that any `FunctionCall.getTarget()`
* should be in this relation.
*/
pragma[noinline]
private predicate isFunction(Element el) {
el instanceof Function
or
el.(Expr).getParent() = el
}
/**
* Holds if `fc` is a `FunctionCall` with no return value for `getTarget`. This
* can happen due to extractor issue CPP-383.
*/
pragma[noopt]
private predicate callHasNoTarget(@funbindexpr fc) {
exists(Function f |
funbind(fc, f) and
not isFunction(f)
)
}
// This base case is pulled out to work around QL-796
private predicate potentiallyReturningFunctionCall_base(FunctionCall fc) {
fc.isVirtual()
or
callHasNoTarget(fc)
}
/** A function call that *may* return; if in doubt, we assume it may. */ /** A function call that *may* return; if in doubt, we assume it may. */
private predicate potentiallyReturningFunctionCall(FunctionCall fc) { private predicate potentiallyReturningFunctionCall(FunctionCall fc) {
potentiallyReturningFunction(fc.getTarget()) or fc.isVirtual() potentiallyReturningFunctionCall_base(fc)
or
potentiallyReturningFunction(fc.getTarget())
} }
/** A function that *may* return; if in doubt, we assume it may. */ /** A function that *may* return; if in doubt, we assume it may. */