Skip to content

Commit 9061536

Browse files
committed
Rust: Make logical operator pre order nodes and eliminate impossible paths in CFG
1 parent 61aad2e commit 9061536

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
6767
override predicate isValidForSpecific(AstNode e) {
6868
e = any(IfExpr c).getCondition()
6969
or
70-
exists(BinaryOpExpr expr | expr.getOp() = ["&&", "||"] and expr.getLhs() = e)
70+
exists(BinaryOpExpr expr |
71+
expr.getOp() = ["&&", "||"] and
72+
e = [expr.getLhs(), expr.getRhs()]
73+
)
7174
}
7275

7376
/** Gets the dual Boolean completion. */

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,45 +69,63 @@ class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryOpExpr {
6969
}
7070
}
7171

72-
class LogicalOrBinaryOpExprTree extends PostOrderTree instanceof BinaryOpExpr {
72+
class LogicalOrBinaryOpExprTree extends PreOrderTree instanceof BinaryOpExpr {
7373
LogicalOrBinaryOpExprTree() { super.getOp() = "||" }
7474

7575
final override predicate propagatesAbnormal(AstNode child) {
7676
child = [super.getRhs(), super.getLhs()]
7777
}
7878

79-
override predicate first(AstNode node) { first(super.getLhs(), node) }
80-
79+
// override predicate first(AstNode node) { first(super.getLhs(), node) }
8180
override predicate succ(AstNode pred, AstNode succ, Completion c) {
81+
// Edge to the first node in the lhs
82+
pred = this and
83+
first(super.getLhs(), succ) and
84+
completionIsSimple(c)
85+
or
86+
// Edge from the last node in the lhs to the first node in the rhs
8287
last(super.getLhs(), pred, c) and
83-
(
84-
succ = this and c.(BooleanCompletion).getValue() = true
85-
or
86-
first(super.getRhs(), succ) and c.(BooleanCompletion).getValue() = false
87-
)
88+
first(super.getRhs(), succ) and
89+
c.(BooleanCompletion).getValue() = false
90+
}
91+
92+
override predicate last(AstNode node, Completion c) {
93+
// Lhs. as the last node
94+
last(super.getLhs(), node, c) and
95+
c.(BooleanCompletion).getValue() = true
8896
or
89-
last(super.getRhs(), pred, c) and succ = this
97+
// Rhs. as the last node
98+
last(super.getRhs(), node, c) // and
9099
}
91100
}
92101

93-
class LogicalAndBinaryOpExprTree extends PostOrderTree instanceof BinaryOpExpr {
102+
class LogicalAndBinaryOpExprTree extends PreOrderTree instanceof BinaryOpExpr {
94103
LogicalAndBinaryOpExprTree() { super.getOp() = "&&" }
95104

96105
final override predicate propagatesAbnormal(AstNode child) {
97106
child = [super.getRhs(), super.getLhs()]
98107
}
99108

100-
override predicate first(AstNode node) { first(super.getLhs(), node) }
101-
109+
// override predicate first(AstNode node) { first(super.getLhs(), node) }
102110
override predicate succ(AstNode pred, AstNode succ, Completion c) {
111+
// Edge to the first node in the lhs
112+
pred = this and
113+
first(super.getLhs(), succ) and
114+
completionIsSimple(c)
115+
or
116+
// Edge from the last node in the lhs to the first node in the rhs
103117
last(super.getLhs(), pred, c) and
104-
(
105-
succ = this and c.(BooleanCompletion).getValue() = false
106-
or
107-
first(super.getRhs(), succ) and c.(BooleanCompletion).getValue() = true
108-
)
118+
first(super.getRhs(), succ) and
119+
c.(BooleanCompletion).getValue() = true
120+
}
121+
122+
override predicate last(AstNode node, Completion c) {
123+
// Lhs. as the last node
124+
last(super.getLhs(), node, c) and
125+
c.(BooleanCompletion).getValue() = false
109126
or
110-
last(super.getRhs(), pred, c) and succ = this
127+
// Rhs. as the last node
128+
last(super.getRhs(), node, c)
111129
}
112130
}
113131

0 commit comments

Comments
 (0)