Skip to content

Commit f8d45f0

Browse files
committed
Revert "Revert "C++: Work around extractor issue CPP-383""
**Revert the revert** of the workaround for CFG issues when a `FunctionCall` has a `getTarget` that does not exist. While we've fixed the main cause of the problem, it can apparently still happen in rare cases as a result of extractor crashes. This reverts commit ee5eaef.
1 parent 3c8ea16 commit f8d45f0

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

cpp/ql/src/semmle/code/cpp/controlflow/internal/ConstantExprs.qll

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,42 @@ private predicate loopConditionAlwaysUponEntry(ControlFlowNode loop, Expr condit
104104
)
105105
}
106106

107+
/**
108+
* This relation is the same as the `el instanceof Function`, only obfuscated
109+
* so the optimizer will not understand that any `FunctionCall.getTarget()`
110+
* should be in this relation.
111+
*/
112+
pragma[noinline]
113+
private predicate isFunction(Element el) {
114+
el instanceof Function
115+
or
116+
el.(Expr).getParent() = el
117+
}
118+
119+
/**
120+
* Holds if `fc` is a `FunctionCall` with no return value for `getTarget`. This
121+
* can happen due to extractor issue CPP-383.
122+
*/
123+
pragma[noopt]
124+
private predicate callHasNoTarget(@funbindexpr fc) {
125+
exists(Function f |
126+
funbind(fc, f) and
127+
not isFunction(f)
128+
)
129+
}
130+
131+
// This base case is pulled out to work around QL-796
132+
private predicate potentiallyReturningFunctionCall_base(FunctionCall fc) {
133+
fc.isVirtual()
134+
or
135+
callHasNoTarget(fc)
136+
}
137+
107138
/** A function call that *may* return; if in doubt, we assume it may. */
108139
private predicate potentiallyReturningFunctionCall(FunctionCall fc) {
109-
potentiallyReturningFunction(fc.getTarget()) or fc.isVirtual()
140+
potentiallyReturningFunctionCall_base(fc)
141+
or
142+
potentiallyReturningFunction(fc.getTarget())
110143
}
111144

112145
/** A function that *may* return; if in doubt, we assume it may. */

0 commit comments

Comments
 (0)