Skip to content

Commit 4da7919

Browse files
committed
C#: Lift barrier guards to logical operations
1 parent 841e6a1 commit 4da7919

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,7 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
10781078
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
10791079
private import csharp as Cs
10801080
private import semmle.code.csharp.controlflow.BasicBlocks
1081+
private import codeql.util.Boolean
10811082

10821083
class Expr extends ControlFlow::Node {
10831084
predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) { this = bb.getNode(i) }
@@ -1114,6 +1115,58 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
11141115
}
11151116
}
11161117

1118+
abstract class LogicalOperationGuard extends Guard {
1119+
abstract Guard getOperand(int i);
1120+
1121+
abstract predicate lift(string id, int i, boolean operandBranch, boolean branch);
1122+
}
1123+
1124+
private class NotGuard extends LogicalOperationGuard, LogicalNotExpr {
1125+
override Guard getOperand(int i) { i = 0 and result = this.getOperand() }
1126+
1127+
override predicate lift(string id, int i, boolean operandBranch, boolean branch) {
1128+
operandBranch instanceof Boolean and
1129+
id = operandBranch.toString() and
1130+
i = 0 and
1131+
branch = operandBranch.booleanNot()
1132+
}
1133+
}
1134+
1135+
abstract private class BinaryLogicalOperationGuard extends LogicalOperationGuard,
1136+
BinaryLogicalOperation
1137+
{
1138+
final override Guard getOperand(int i) {
1139+
i = 0 and result = this.getLeftOperand()
1140+
or
1141+
i = 1 and result = this.getRightOperand()
1142+
}
1143+
1144+
abstract predicate lift(Boolean branchLeft, Boolean branchRight, boolean branch);
1145+
1146+
final override predicate lift(string id, int i, boolean operandBranch, boolean branch) {
1147+
exists(Boolean branchLeft, Boolean branchRight |
1148+
this.lift(branchLeft, branchRight, branch) and
1149+
id = branchLeft + "," + branchRight
1150+
|
1151+
i = 0 and operandBranch = branchLeft
1152+
or
1153+
i = 1 and operandBranch = branchRight
1154+
)
1155+
}
1156+
}
1157+
1158+
private class AndGuard extends BinaryLogicalOperationGuard, LogicalAndExpr {
1159+
override predicate lift(Boolean branchLeft, Boolean branchRight, boolean branch) {
1160+
branch = branchLeft.booleanOr(branchRight) // yes, should not be `booleanAnd`
1161+
}
1162+
}
1163+
1164+
private class OrGuard extends BinaryLogicalOperationGuard, LogicalOrExpr {
1165+
override predicate lift(Boolean branchLeft, Boolean branchRight, boolean branch) {
1166+
branch = branchLeft.booleanAnd(branchRight) // yes, should not be `booleanOr`
1167+
}
1168+
}
1169+
11171170
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
11181171
predicate guardControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
11191172
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |

csharp/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.expected

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ edges
88
| BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | BarrierFlow.cs:103:18:103:18 | access to local variable x | provenance | |
99
| BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | BarrierFlow.cs:112:18:112:18 | access to local variable x | provenance | |
1010
| BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | BarrierFlow.cs:117:18:117:18 | access to local variable x | provenance | |
11-
| BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | BarrierFlow.cs:121:18:121:18 | access to local variable x | provenance | |
1211
| BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | BarrierFlow.cs:126:18:126:18 | access to local variable x | provenance | |
13-
| BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | BarrierFlow.cs:130:18:130:18 | access to local variable x | provenance | |
1412
| BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:86:13:86:13 | access to local variable x : Object | provenance | |
1513
| BarrierFlow.cs:136:13:136:13 | access to local variable x : Object | BarrierFlow.cs:144:18:144:18 | access to local variable x | provenance | |
1614
| BarrierFlow.cs:136:13:136:13 | access to local variable x : Object | BarrierFlow.cs:149:18:149:18 | access to local variable x | provenance | |
@@ -31,9 +29,7 @@ nodes
3129
| BarrierFlow.cs:103:18:103:18 | access to local variable x | semmle.label | access to local variable x |
3230
| BarrierFlow.cs:112:18:112:18 | access to local variable x | semmle.label | access to local variable x |
3331
| BarrierFlow.cs:117:18:117:18 | access to local variable x | semmle.label | access to local variable x |
34-
| BarrierFlow.cs:121:18:121:18 | access to local variable x | semmle.label | access to local variable x |
3532
| BarrierFlow.cs:126:18:126:18 | access to local variable x | semmle.label | access to local variable x |
36-
| BarrierFlow.cs:130:18:130:18 | access to local variable x | semmle.label | access to local variable x |
3733
| BarrierFlow.cs:136:13:136:13 | access to local variable x : Object | semmle.label | access to local variable x : Object |
3834
| BarrierFlow.cs:136:17:136:25 | call to method Source : Object | semmle.label | call to method Source : Object |
3935
| BarrierFlow.cs:144:18:144:18 | access to local variable x | semmle.label | access to local variable x |
@@ -43,18 +39,14 @@ nodes
4339
| BarrierFlow.cs:176:18:176:18 | access to local variable x | semmle.label | access to local variable x |
4440
subpaths
4541
testFailures
46-
| BarrierFlow.cs:121:18:121:18 | access to local variable x | Unexpected result: hasValueFlow=7 |
47-
| BarrierFlow.cs:130:18:130:18 | access to local variable x | Unexpected result: hasValueFlow=7 |
4842
#select
4943
| BarrierFlow.cs:12:14:12:14 | access to local variable x | BarrierFlow.cs:10:17:10:25 | call to method Source : Object | BarrierFlow.cs:12:14:12:14 | access to local variable x | $@ | BarrierFlow.cs:10:17:10:25 | call to method Source : Object | call to method Source : Object |
5044
| BarrierFlow.cs:21:18:21:18 | access to local variable x | BarrierFlow.cs:17:17:17:25 | call to method Source : Object | BarrierFlow.cs:21:18:21:18 | access to local variable x | $@ | BarrierFlow.cs:17:17:17:25 | call to method Source : Object | call to method Source : Object |
5145
| BarrierFlow.cs:94:18:94:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:94:18:94:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
5246
| BarrierFlow.cs:103:18:103:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:103:18:103:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
5347
| BarrierFlow.cs:112:18:112:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:112:18:112:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
5448
| BarrierFlow.cs:117:18:117:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:117:18:117:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
55-
| BarrierFlow.cs:121:18:121:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:121:18:121:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
5649
| BarrierFlow.cs:126:18:126:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:126:18:126:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
57-
| BarrierFlow.cs:130:18:130:18 | access to local variable x | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | BarrierFlow.cs:130:18:130:18 | access to local variable x | $@ | BarrierFlow.cs:86:17:86:25 | call to method Source : Object | call to method Source : Object |
5850
| BarrierFlow.cs:144:18:144:18 | access to local variable x | BarrierFlow.cs:136:17:136:25 | call to method Source : Object | BarrierFlow.cs:144:18:144:18 | access to local variable x | $@ | BarrierFlow.cs:136:17:136:25 | call to method Source : Object | call to method Source : Object |
5951
| BarrierFlow.cs:149:18:149:18 | access to local variable x | BarrierFlow.cs:136:17:136:25 | call to method Source : Object | BarrierFlow.cs:149:18:149:18 | access to local variable x | $@ | BarrierFlow.cs:136:17:136:25 | call to method Source : Object | call to method Source : Object |
6052
| BarrierFlow.cs:158:18:158:18 | access to local variable x | BarrierFlow.cs:136:17:136:25 | call to method Source : Object | BarrierFlow.cs:158:18:158:18 | access to local variable x | $@ | BarrierFlow.cs:136:17:136:25 | call to method Source : Object | call to method Source : Object |

0 commit comments

Comments
 (0)