Skip to content

Commit cbc96db

Browse files
committed
Shared CFG: Add another consistency test
Finds nodes with multiple normal successors, where one is the special simple successor. For example, this would flag a node that has both a "simple" and a "true" successor.
1 parent 9ffa236 commit cbc96db

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,10 +957,31 @@ module Consistency {
957957
not split.hasEntry(pred, succ, c)
958958
}
959959

960+
private class SimpleSuccessorType extends SuccessorType {
961+
SimpleSuccessorType() {
962+
this = getAMatchingSuccessorType(any(Completion c | completionIsSimple(c)))
963+
}
964+
}
965+
966+
private class NormalSuccessorType extends SuccessorType {
967+
NormalSuccessorType() {
968+
this = getAMatchingSuccessorType(any(Completion c | completionIsNormal(c)))
969+
}
970+
}
971+
960972
query predicate multipleSuccessors(Node node, SuccessorType t, Node successor) {
961-
not node instanceof TEntryNode and
962973
strictcount(getASuccessor(node, t)) > 1 and
963-
successor = getASuccessor(node, t)
974+
successor = getASuccessor(node, t) and
975+
// allow for functions with multiple bodies
976+
not (t instanceof SimpleSuccessorType and node instanceof TEntryNode)
977+
}
978+
979+
query predicate simpleAndNormalSuccessors(
980+
Node node, NormalSuccessorType t1, SimpleSuccessorType t2, Node succ1, Node succ2
981+
) {
982+
t1 != t2 and
983+
succ1 = getASuccessor(node, t1) and
984+
succ2 = getASuccessor(node, t2)
964985
}
965986

966987
query predicate deadEnd(Node node) {

ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,10 +957,31 @@ module Consistency {
957957
not split.hasEntry(pred, succ, c)
958958
}
959959

960+
private class SimpleSuccessorType extends SuccessorType {
961+
SimpleSuccessorType() {
962+
this = getAMatchingSuccessorType(any(Completion c | completionIsSimple(c)))
963+
}
964+
}
965+
966+
private class NormalSuccessorType extends SuccessorType {
967+
NormalSuccessorType() {
968+
this = getAMatchingSuccessorType(any(Completion c | completionIsNormal(c)))
969+
}
970+
}
971+
960972
query predicate multipleSuccessors(Node node, SuccessorType t, Node successor) {
961-
not node instanceof TEntryNode and
962973
strictcount(getASuccessor(node, t)) > 1 and
963-
successor = getASuccessor(node, t)
974+
successor = getASuccessor(node, t) and
975+
// allow for functions with multiple bodies
976+
not (t instanceof SimpleSuccessorType and node instanceof TEntryNode)
977+
}
978+
979+
query predicate simpleAndNormalSuccessors(
980+
Node node, NormalSuccessorType t1, SimpleSuccessorType t2, Node succ1, Node succ2
981+
) {
982+
t1 != t2 and
983+
succ1 = getASuccessor(node, t1) and
984+
succ2 = getASuccessor(node, t2)
964985
}
965986

966987
query predicate deadEnd(Node node) {

0 commit comments

Comments
 (0)