Skip to content

Commit

Permalink
Merge pull request #18307 from MathiasVP/fix-more-join-orders-in-data…
Browse files Browse the repository at this point in the history
…flow

C++: Fix two more dataflow-related joins
  • Loading branch information
MathiasVP authored Dec 17, 2024
2 parents 8efd870 + 2cc6ffb commit dfb3483
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
46 changes: 36 additions & 10 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -2288,6 +2288,15 @@ private predicate controls(IRGuardCondition g, Node n, boolean edge) {
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
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.
*
Expand Down Expand Up @@ -2321,9 +2330,8 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
* 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)
Expand Down Expand Up @@ -2374,6 +2382,17 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
*/
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.
Expand Down Expand Up @@ -2409,9 +2428,8 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
* 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)
Expand Down Expand Up @@ -2450,12 +2468,20 @@ private EdgeKind getConditionalEdge(boolean branch) {
* in data flow and taint tracking.
*/
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down

0 comments on commit dfb3483

Please sign in to comment.