diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 8f0ae53171e3..7b89e9714ff0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -1237,12 +1237,14 @@ module IsUnreachableInCall { int getValue() { result = value } } - pragma[nomagic] + bindingset[right] + pragma[inline_late] private predicate ensuresEq(Operand left, Operand right, int k, IRBlock block, boolean areEqual) { any(G::IRGuardCondition guard).ensuresEq(left, right, k, block, areEqual) } - pragma[nomagic] + bindingset[right] + pragma[inline_late] private predicate ensuresLt(Operand left, Operand right, int k, IRBlock block, boolean areEqual) { any(G::IRGuardCondition guard).ensuresLt(left, right, k, block, areEqual) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 32dec1355ea9..5a5607dbf3bf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -2275,7 +2275,7 @@ private predicate guardControlsPhiInput( */ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch); -bindingset[g, n] +bindingset[g] pragma[inline_late] private predicate controls(IRGuardCondition g, Node n, boolean edge) { g.controls(n.getBasicBlock(), edge) @@ -2288,6 +2288,15 @@ private predicate controls(IRGuardCondition g, Node n, boolean edge) { * in data flow and taint tracking. */ module BarrierGuard { + bindingset[value, n] + pragma[inline_late] + private predicate convertedExprHasValueNumber(ValueNumber value, Node n) { + exists(Expr e | + e = value.getAnInstruction().getConvertedResultExpression() and + n.asConvertedExpr() = e + ) + } + /** * Gets an expression node that is safely guarded by the given guard check. * @@ -2321,9 +2330,8 @@ module BarrierGuard { * NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead. */ Node getABarrierNode() { - exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge | - e = value.getAnInstruction().getConvertedResultExpression() and - result.asConvertedExpr() = e and + exists(IRGuardCondition g, ValueNumber value, boolean edge | + convertedExprHasValueNumber(value, result) and guardChecks(g, pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and controls(g, result, edge) @@ -2374,6 +2382,17 @@ module BarrierGuard { */ Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) } + bindingset[value, n] + pragma[inline_late] + private predicate indirectConvertedExprHasValueNumber( + int indirectionIndex, ValueNumber value, Node n + ) { + exists(Expr e | + e = value.getAnInstruction().getConvertedResultExpression() and + n.asIndirectConvertedExpr(indirectionIndex) = e + ) + } + /** * Gets an indirect expression node with indirection index `indirectionIndex` that is * safely guarded by the given guard check. @@ -2409,9 +2428,8 @@ module BarrierGuard { * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead. */ Node getAnIndirectBarrierNode(int indirectionIndex) { - exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge | - e = value.getAnInstruction().getConvertedResultExpression() and - result.asIndirectConvertedExpr(indirectionIndex) = e and + exists(IRGuardCondition g, ValueNumber value, boolean edge | + indirectConvertedExprHasValueNumber(indirectionIndex, value, result) and guardChecks(g, pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and controls(g, result, edge) @@ -2450,12 +2468,20 @@ private EdgeKind getConditionalEdge(boolean branch) { * in data flow and taint tracking. */ module InstructionBarrierGuard { + bindingset[value, n] + pragma[inline_late] + private predicate operandHasValueNumber(ValueNumber value, Node n) { + exists(Operand use | + use = value.getAnInstruction().getAUse() and + n.asOperand() = use + ) + } + /** Gets a node that is safely guarded by the given guard check. */ Node getABarrierNode() { - exists(IRGuardCondition g, ValueNumber value, boolean edge, Operand use | + exists(IRGuardCondition g, ValueNumber value, boolean edge | instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and - use = value.getAnInstruction().getAUse() and - result.asOperand() = use and + operandHasValueNumber(value, result) and controls(g, result, edge) ) or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll index 2a46e16c52fe..279b43a1ca8b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/ValueNumbering.qll @@ -51,6 +51,7 @@ class ValueNumber extends TValueNumber { /** * Gets an `Operand` whose definition is exact and has this value number. */ + pragma[nomagic] final Operand getAUse() { this = valueNumber(result.getDef()) } final string getKind() { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll index 2a46e16c52fe..279b43a1ca8b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/ValueNumbering.qll @@ -51,6 +51,7 @@ class ValueNumber extends TValueNumber { /** * Gets an `Operand` whose definition is exact and has this value number. */ + pragma[nomagic] final Operand getAUse() { this = valueNumber(result.getDef()) } final string getKind() { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll index 2a46e16c52fe..279b43a1ca8b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll @@ -51,6 +51,7 @@ class ValueNumber extends TValueNumber { /** * Gets an `Operand` whose definition is exact and has this value number. */ + pragma[nomagic] final Operand getAUse() { this = valueNumber(result.getDef()) } final string getKind() {