Skip to content

Commit 4d3076a

Browse files
committed
C++: Don't constant fold small binary operations.
1 parent e16e1c7 commit 4d3076a

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,28 @@ IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
4040
result.getTag() = tag
4141
}
4242

43+
private Expr getAnOperand(BinaryOperation binOp) { result = binOp.getAnOperand() }
44+
45+
private int getNumberOfBinaryOperands(BinaryOperation binOp) {
46+
result = count(getAnOperand*(binOp))
47+
}
48+
4349
/**
4450
* Holds if `expr` is a constant of a type that can be replaced directly with
4551
* its value in the IR. This does not include address constants as we have no
4652
* means to express those as QL values.
4753
*/
48-
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
54+
predicate isIRConstant(Expr expr) {
55+
exists(expr.getValue()) and
56+
// We avoid constant folding binary operations since it's often useful to
57+
// mark one of those as a source in dataflow, and if the operation is
58+
// constant folded it's not possible to mark its operands as a source (or
59+
// sink).
60+
// But to avoid creating an outrageous amount of IR from very large
61+
// constant expressions we fall back to constant folding if the operation
62+
// has more than 50 operands (i.e., 1 + 2 + 3 + 4 + ... + 50)
63+
if expr instanceof BinaryOperation then getNumberOfBinaryOperands(expr) > 50 else any()
64+
}
4965

5066
// Pulled out for performance. See
5167
// https://github.com/github/codeql-coreql-team/issues/1044.

0 commit comments

Comments
 (0)