Skip to content

Commit f5e6b79

Browse files
committed
C#: Address review comments
1 parent 6651736 commit f5e6b79

File tree

3 files changed

+94
-55
lines changed

3 files changed

+94
-55
lines changed

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

Lines changed: 86 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -404,21 +404,15 @@ class NullGuardedExpr extends GuardedExpr {
404404
/** INTERNAL: Do not use. */
405405
module Internal {
406406
private import ControlFlow::Internal
407-
/**
408-
* Gets the conditional qualifier of `e`, if any, where `e` is an access/call
409-
* with a value type, lifted to a nullable type by the conditional access.
410-
*/
411-
Expr getConditionalQualifier(Expr e) {
412-
result = any(QualifiableExpr qe |
413-
qe.getQualifier() = e and
414-
qe.isConditional() and
415-
(
416-
result.(FieldAccess).getTarget().getType() instanceof ValueType
417-
or
418-
result.(Call).getTarget().getReturnType() instanceof ValueType
419-
)
420-
)
421-
}
407+
408+
newtype TAbstractValue =
409+
TBooleanValue(boolean b) { b = true or b = false }
410+
or
411+
TNullValue(boolean b) { b = true or b = false }
412+
or
413+
TMatchValue(CaseStmt cs, boolean b) { b = true or b = false }
414+
or
415+
TEmptyCollectionValue(boolean b) { b = true or b = false }
422416

423417
/**
424418
* Gets the parent expression of `e` which is `null` only if `e` is `null`,
@@ -495,16 +489,6 @@ module Internal {
495489
}
496490

497491
private cached module Cached {
498-
cached
499-
newtype TAbstractValue =
500-
TBooleanValue(boolean b) { b = true or b = false }
501-
or
502-
TNullValue(boolean b) { b = true or b = false }
503-
or
504-
TMatchValue(CaseStmt cs, boolean b) { b = true or b = false }
505-
or
506-
TEmptyCollectionValue(boolean b) { b = true or b = false }
507-
508492
cached
509493
predicate isGuardedBy(AccessOrCallExpr guarded, Expr e, AccessOrCallExpr sub, AbstractValue v) {
510494
exists(BasicBlock bb |
@@ -523,57 +507,104 @@ module Internal {
523507
*/
524508
cached
525509
predicate impliesStep(Expr e1, AbstractValue v1, Expr e2, AbstractValue v2) {
526-
e1.(BitwiseAndExpr).getAnOperand() = e2 and
527-
v1 = TBooleanValue(true) and
528-
v2 = v1
529-
or
530-
e1.(BitwiseOrExpr).getAnOperand() = e2 and
531-
v1 = TBooleanValue(false) and
532-
v2 = v1
533-
or
534-
e1.(LogicalAndExpr).getAnOperand() = e2 and
535-
v1 = TBooleanValue(true) and
536-
v2 = v1
510+
exists(BinaryOperation bo |
511+
bo instanceof BitwiseAndExpr or
512+
bo instanceof LogicalAndExpr
513+
|
514+
bo = e1 and
515+
e2 = bo.getAnOperand() and
516+
v1 = TBooleanValue(true) and
517+
v2 = v1
518+
or
519+
bo = e2 and
520+
e1 = bo.getAnOperand() and
521+
v1 = TBooleanValue(false) and
522+
v2 = v1
523+
)
537524
or
538-
e1.(LogicalOrExpr).getAnOperand() = e2 and
539-
v1 = TBooleanValue(false) and
540-
v2 = v1
525+
exists(BinaryOperation bo |
526+
bo instanceof BitwiseOrExpr or
527+
bo instanceof LogicalOrExpr
528+
|
529+
bo = e1 and
530+
e2 = bo.getAnOperand() and
531+
v1 = TBooleanValue(false) and
532+
v2 = v1
533+
or
534+
bo = e2 and
535+
e1 = bo.getAnOperand() and
536+
v1 = TBooleanValue(true) and
537+
v2 = v1
538+
)
541539
or
542540
e1.(LogicalNotExpr).getOperand() = e2 and
543541
v2 = TBooleanValue(v1.(BooleanValue).getValue().booleanNot())
544542
or
545-
exists(ComparisonTest ct, boolean polarity, BoolLiteral boolLit |
546-
e1 = ct.getExpr() and
547-
ct.getAnArgument() = e2 and
543+
e1 = e2.(LogicalNotExpr).getOperand() and
544+
v2 = TBooleanValue(v1.(BooleanValue).getValue().booleanNot())
545+
or
546+
exists(ComparisonTest ct, boolean polarity, BoolLiteral boolLit, boolean b |
548547
ct.getAnArgument() = boolLit and
549-
v2 = TBooleanValue(v1.(BooleanValue).getValue().booleanXor(polarity).booleanXor(boolLit.getBoolValue())) |
548+
b = boolLit.getBoolValue() and
549+
v2 = TBooleanValue(v1.(BooleanValue).getValue().booleanXor(polarity).booleanXor(b)) |
550550
ct.getComparisonKind().isEquality() and
551-
polarity = true
551+
polarity = true and
552+
(
553+
// e1 === e2 == b, v1 === !(v2 xor b)
554+
e1 = ct.getExpr() and
555+
e2 = ct.getAnArgument()
556+
or
557+
// e2 === e1 == b, v1 === !(v2 xor b)
558+
e1 = ct.getAnArgument() and
559+
e2 = ct.getExpr()
560+
)
552561
or
553562
ct.getComparisonKind().isInequality() and
554-
polarity = false
563+
polarity = false and
564+
(
565+
// e1 === e2 != b, v1 === v2 xor b
566+
e1 = ct.getExpr() and
567+
e2 = ct.getAnArgument()
568+
or
569+
// e2 === e1 != true, v1 === v2 xor b
570+
e1 = ct.getAnArgument() and
571+
e2 = ct.getExpr()
572+
)
555573
)
556574
or
557-
exists(ConditionalExpr cond, boolean branch, BoolLiteral boolLit, boolean boolVal |
558-
cond.getThen() = boolLit and branch = true
559-
or
560-
cond.getElse() = boolLit and branch = false
561-
|
562-
cond = e1 and
563-
boolVal = boolLit.getBoolValue() and
564-
v1 = TBooleanValue(boolVal.booleanNot()) and
575+
exists(ConditionalExpr cond, boolean branch, BoolLiteral boolLit, boolean b |
576+
b = boolLit.getBoolValue() and
565577
(
578+
cond.getThen() = boolLit and branch = true
579+
or
580+
cond.getElse() = boolLit and branch = false
581+
)
582+
|
583+
e1 = cond and
584+
v1 = TBooleanValue(b.booleanNot()) and
585+
(
586+
// e1 === e2 ? b : x, v1 === !b, v2 === false; or
587+
// e1 === e2 ? x : b, v1 === !b, v2 === true
566588
e2 = cond.getCondition() and
567589
v2 = TBooleanValue(branch.booleanNot())
568590
or
591+
// e1 === x ? e2 : b, v1 === !b, v2 === v1
569592
e2 = cond.getThen() and
570-
e2 != boolLit and
593+
branch = false and
571594
v2 = v1
572595
or
596+
// e1 === x ? b : e2, v1 === !b, v2 === v1
573597
e2 = cond.getElse() and
574-
e2 != boolLit and
598+
branch = true and
575599
v2 = v1
576600
)
601+
or
602+
// e2 === e1 ? b : x, v1 === true, v2 === b; or
603+
// e2 === e1 ? x : b, v1 === false, v2 === b
604+
e1 = cond.getCondition() and
605+
e2 = cond and
606+
v1 = TBooleanValue(branch) and
607+
v2 = TBooleanValue(b)
577608
)
578609
or
579610
exists(boolean isNull |

csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:13:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | false |
2+
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:14:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | true |
13
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
4+
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:13:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | false |
5+
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:14:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | true |
26
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
37
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:12:13:12:24 | ... > ... | Guards.cs:12:13:12:13 | access to parameter s | true |
48
| Guards.cs:26:31:26:31 | access to parameter s | Guards.cs:24:13:24:21 | ... != ... | Guards.cs:24:13:24:13 | access to parameter s | true |

csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:13:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | false |
2+
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:14:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | true |
13
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |
24
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
5+
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:13:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | false |
6+
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:14:10:25 | !... | Guards.cs:10:16:10:16 | access to parameter s | true |
37
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |
48
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
59
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:12:13:12:24 | ... > ... | Guards.cs:12:13:12:13 | access to parameter s | true |

0 commit comments

Comments
 (0)