Skip to content

Commit e10ea73

Browse files
authored
Merge pull request #901 from hvitved/csharp/conditional-assign-join-order
C#: Improve join order in `conditionalAssign()`
2 parents b557b7b + 23e63e9 commit e10ea73

File tree

1 file changed

+49
-10
lines changed
  • csharp/ql/src/semmle/code/csharp/controlflow

1 file changed

+49
-10
lines changed

csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,48 @@ module Internal {
896896
)
897897
}
898898

899+
pragma[noinline]
900+
private predicate conditionalAssign0(
901+
Guard guard, AbstractValue vGuard, PreSsa::Definition def, Expr e, PreSsa::Definition upd,
902+
PreBasicBlocks::PreBasicBlock bbGuard
903+
) {
904+
e = upd.getDefinition().getSource() and
905+
upd = def.getAPhiInput() and
906+
guard.preControlsDirect(upd.getBasicBlock(), vGuard) and
907+
bbGuard.getAnElement() = guard and
908+
bbGuard.strictlyDominates(def.getBasicBlock()) and
909+
not guard.preControlsDirect(def.getBasicBlock(), vGuard)
910+
}
911+
912+
pragma[noinline]
913+
private predicate conditionalAssign1(
914+
Guard guard, AbstractValue vGuard, PreSsa::Definition def, Expr e, PreSsa::Definition upd,
915+
PreBasicBlocks::PreBasicBlock bbGuard, PreSsa::Definition other
916+
) {
917+
conditionalAssign0(guard, vGuard, def, e, upd, bbGuard) and
918+
other != upd and
919+
other = def.getAPhiInput()
920+
}
921+
922+
pragma[noinline]
923+
private predicate conditionalAssign2(
924+
Guard guard, AbstractValue vGuard, PreSsa::Definition def, Expr e, PreSsa::Definition upd,
925+
PreBasicBlocks::PreBasicBlock bbGuard, PreSsa::Definition other
926+
) {
927+
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard, other) and
928+
guard.preControlsDirect(other.getBasicBlock(), vGuard.getDualValue())
929+
}
930+
931+
pragma[noinline]
932+
private predicate conditionalAssign3(
933+
Guard guard, AbstractValue vGuard, PreSsa::Definition def, Expr e, PreSsa::Definition upd,
934+
PreBasicBlocks::PreBasicBlock bbGuard, PreSsa::Definition other
935+
) {
936+
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard, other) and
937+
other.getBasicBlock().dominates(bbGuard) and
938+
not PreSsa::ssaDefReachesEndOfBlock(guard.getConditionalSuccessor(vGuard), other, _)
939+
}
940+
899941
/**
900942
* Holds if the evaluation of `guard` to `vGuard` implies that `def` is assigned
901943
* expression `e`.
@@ -917,28 +959,25 @@ module Internal {
917959
)
918960
or
919961
exists(PreSsa::Definition upd, PreBasicBlocks::PreBasicBlock bbGuard |
920-
e = upd.getDefinition().getSource() and
921-
upd = def.getAPhiInput() and
922-
guard.preControlsDirect(upd.getBasicBlock(), vGuard) and
923-
bbGuard.getAnElement() = guard and
924-
bbGuard.strictlyDominates(def.getBasicBlock()) and
925-
not guard.preControlsDirect(def.getBasicBlock(), vGuard) and
926-
forall(PreSsa::Definition other | other != upd and other = def.getAPhiInput() |
962+
conditionalAssign0(guard, vGuard, def, e, upd, bbGuard)
963+
|
964+
forall(PreSsa::Definition other |
965+
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard, other)
966+
|
927967
// For example:
928968
// if (guard)
929969
// upd = a;
930970
// else
931971
// other = b;
932972
// def = phi(upd, other)
933-
guard.preControlsDirect(other.getBasicBlock(), vGuard.getDualValue())
973+
conditionalAssign2(guard, vGuard, def, e, upd, bbGuard, other)
934974
or
935975
// For example:
936976
// other = a;
937977
// if (guard)
938978
// upd = b;
939979
// def = phi(other, upd)
940-
other.getBasicBlock().dominates(bbGuard) and
941-
not PreSsa::ssaDefReachesEndOfBlock(guard.getConditionalSuccessor(vGuard), other, _)
980+
conditionalAssign3(guard, vGuard, def, e, upd, bbGuard, other)
942981
)
943982
)
944983
}

0 commit comments

Comments
 (0)