mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
Merge pull request #15969 from MathiasVP/disable-some-constant-folding
C++: Disable _some_ constant folding in IR
This commit is contained in:
@@ -38,6 +38,12 @@ private int getBinaryInstructionValue(BinaryInstruction instr) {
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof BitOrInstruction and result = bitOr(left, right)
|
||||
or
|
||||
instr instanceof BitAndInstruction and result = bitAnd(left, right)
|
||||
or
|
||||
instr instanceof BitXorInstruction and result = bitXor(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
|
||||
@@ -38,6 +38,12 @@ private int getBinaryInstructionValue(BinaryInstruction instr) {
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof BitOrInstruction and result = bitOr(left, right)
|
||||
or
|
||||
instr instanceof BitAndInstruction and result = bitAnd(left, right)
|
||||
or
|
||||
instr instanceof BitXorInstruction and result = bitXor(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
|
||||
@@ -40,12 +40,43 @@ IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
|
||||
result.getTag() = tag
|
||||
}
|
||||
|
||||
/** Gets an operand of `op`. */
|
||||
private Expr getAnOperand(Operation op) { result = op.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the number of nested operands of `op`. For example,
|
||||
* `getNumberOfNestedBinaryOperands((1 + 2) + 3))` is `3`.
|
||||
*/
|
||||
private int getNumberOfNestedBinaryOperands(Operation op) { result = count(getAnOperand*(op)) }
|
||||
|
||||
/**
|
||||
* Holds if `op` should not be translated to a `ConstantInstruction` as part of
|
||||
* IR generation, even if the value of `op` is constant.
|
||||
*/
|
||||
private predicate ignoreConstantValue(Operation op) {
|
||||
op instanceof BitwiseAndExpr
|
||||
or
|
||||
op instanceof BitwiseOrExpr
|
||||
or
|
||||
op instanceof BitwiseXorExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `expr` is a constant of a type that can be replaced directly with
|
||||
* its value in the IR. This does not include address constants as we have no
|
||||
* means to express those as QL values.
|
||||
*/
|
||||
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
|
||||
predicate isIRConstant(Expr expr) {
|
||||
exists(expr.getValue()) and
|
||||
// We avoid constant folding certain operations since it's often useful to
|
||||
// mark one of those as a source in dataflow, and if the operation is
|
||||
// constant folded it's not possible to mark its operands as a source (or
|
||||
// sink).
|
||||
// But to avoid creating an outrageous amount of IR from very large
|
||||
// constant expressions we fall back to constant folding if the operation
|
||||
// has more than 50 operands (i.e., 1 + 2 + 3 + 4 + ... + 50)
|
||||
if ignoreConstantValue(expr) then getNumberOfNestedBinaryOperands(expr) > 50 else any()
|
||||
}
|
||||
|
||||
// Pulled out for performance. See
|
||||
// https://github.com/github/codeql-coreql-team/issues/1044.
|
||||
|
||||
@@ -38,6 +38,12 @@ private int getBinaryInstructionValue(BinaryInstruction instr) {
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof BitOrInstruction and result = bitOr(left, right)
|
||||
or
|
||||
instr instanceof BitAndInstruction and result = bitAnd(left, right)
|
||||
or
|
||||
instr instanceof BitXorInstruction and result = bitXor(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
|
||||
@@ -89,6 +89,18 @@ int compareLE(int a, int b) { if a <= b then result = 1 else result = 0 }
|
||||
bindingset[a, b]
|
||||
int compareGE(int a, int b) { if a >= b then result = 1 else result = 0 }
|
||||
|
||||
/** Returns `a | b`. */
|
||||
bindingset[a, b]
|
||||
int bitOr(int a, int b) { result = a.bitOr(b) }
|
||||
|
||||
/** Returns `a & b`. */
|
||||
bindingset[a, b]
|
||||
int bitAnd(int a, int b) { result = a.bitAnd(b) }
|
||||
|
||||
/** Returns `a ^ b`. */
|
||||
bindingset[a, b]
|
||||
int bitXor(int a, int b) { result = a.bitXor(b) }
|
||||
|
||||
/**
|
||||
* Returns `-a`. If the negation would overflow, there is no result.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user