Skip to content

Commit 4f6528a

Browse files
committed
C#: Deprecate AbstractValue.
1 parent 09378b8 commit 4f6528a

File tree

16 files changed

+81
-83
lines changed

16 files changed

+81
-83
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: deprecated
3+
---
4+
* The class `AbstractValue` in the `Guards` library has been deprecated and replaced with the class `GuardValue`.

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

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ private module LogicInput implements GuardsImpl::LogicInputSig {
227227
e instanceof DereferenceableExpr and
228228
ct.getAnArgument() = e and
229229
ct.getAnArgument() = arg and
230-
arg = any(NullValue nv | nv.isNonNull()).getAnExpr() and
230+
nonNullValueImplied(arg) and
231231
ck = ct.getComparisonKind() and
232232
e != arg and
233233
isNull = false and
@@ -314,7 +314,7 @@ class Guard extends Guards::Guard {
314314
* In case `cfn` or `sub` access an SSA variable in their left-most qualifier, then
315315
* so must the other (accessing the same SSA variable).
316316
*/
317-
predicate controlsNode(ControlFlow::Nodes::ElementNode cfn, AccessOrCallExpr sub, AbstractValue v) {
317+
predicate controlsNode(ControlFlow::Nodes::ElementNode cfn, AccessOrCallExpr sub, GuardValue v) {
318318
isGuardedByNode(cfn, this, sub, v)
319319
}
320320

@@ -324,26 +324,31 @@ class Guard extends Guards::Guard {
324324
* Note: This predicate is inlined.
325325
*/
326326
pragma[inline]
327-
predicate controlsNode(ControlFlow::Nodes::ElementNode cfn, AbstractValue v) {
327+
predicate controlsNode(ControlFlow::Nodes::ElementNode cfn, GuardValue v) {
328328
guardControls(this, cfn.getBasicBlock(), v)
329329
}
330330

331331
/**
332332
* Holds if basic block `bb` is guarded by this expression having value `v`.
333333
*/
334-
predicate controlsBasicBlock(BasicBlock bb, AbstractValue v) { guardControls(this, bb, v) }
334+
predicate controlsBasicBlock(BasicBlock bb, GuardValue v) { guardControls(this, bb, v) }
335335

336336
/**
337337
* Gets a valid value for this guard. For example, if this guard is a test, then
338338
* it can have Boolean values `true` and `false`.
339339
*/
340-
deprecated AbstractValue getAValue() { isGuard(this, result) }
340+
deprecated GuardValue getAValue() { isGuard(this, result) }
341341
}
342342

343-
class AbstractValue = GuardValue;
343+
/** DEPRECATED: Use `GuardValue` instead. */
344+
deprecated class AbstractValue = GuardValue;
344345

345-
/** Provides different types of `AbstractValues`s. */
346-
module AbstractValues {
346+
/**
347+
* DEPRECATED: Use `GuardValue` member predicates instead.
348+
*
349+
* Provides different types of `AbstractValues`s.
350+
*/
351+
deprecated module AbstractValues {
347352
class BooleanValue extends AbstractValue {
348353
BooleanValue() { exists(this.asBooleanValue()) }
349354

@@ -369,8 +374,7 @@ module AbstractValues {
369374
}
370375
}
371376

372-
private import AbstractValues
373-
377+
// private import AbstractValues
374378
/** Gets the value resulting from matching `null` against `pat`. */
375379
private boolean patternMatchesNull(PatternExpr pat) {
376380
pat instanceof NullLiteral and result = true
@@ -431,22 +435,22 @@ class DereferenceableExpr extends Expr {
431435
/**
432436
* Gets an expression that tests via nullness whether this expression is `null`.
433437
*
434-
* If the returned expression evaluates to `null` (`v.isNull()`) or evaluates to
435-
* non-`null` (`not v.isNull()`), then this expression is guaranteed to be `null`
438+
* If the returned expression evaluates to `null` (`v.isNullValue()`) or evaluates to
439+
* non-`null` (`not v.isNullValue()`), then this expression is guaranteed to be `null`
436440
* if `isNull` is true, and non-`null` if `isNull` is false.
437441
*
438442
* For example, if `x` evaluates to `null` in `x ?? y` then `y` is evaluated, and
439443
* `x` is guaranteed to be `null`.
440444
*/
441-
private Expr getANullnessNullCheck(NullValue v, boolean isNull) {
445+
private Expr getANullnessNullCheck(GuardValue v, boolean isNull) {
442446
exists(NullnessCompletion c | c.isValidFor(this) |
443447
result = this and
444448
if c.isNull()
445449
then (
446-
v.isNull() and
450+
v.isNullValue() and
447451
isNull = true
448452
) else (
449-
v.isNonNull() and
453+
v.isNonNullValue() and
450454
isNull = false
451455
)
452456
)
@@ -513,8 +517,8 @@ class EnumerableCollectionExpr extends Expr {
513517
)
514518
}
515519

516-
private Expr getABooleanEmptinessCheck(BooleanValue v, boolean isEmpty) {
517-
exists(boolean branch | branch = v.getValue() |
520+
private Expr getABooleanEmptinessCheck(GuardValue v, boolean isEmpty) {
521+
exists(boolean branch | branch = v.asBooleanValue() |
518522
result =
519523
any(ComparisonTest ct |
520524
exists(boolean lowerBound |
@@ -578,7 +582,7 @@ class EnumerableCollectionExpr extends Expr {
578582
* For example, if the expression `x.Length != 0` evaluates to `true` then the
579583
* expression `x` is guaranteed to be non-empty.
580584
*/
581-
Expr getAnEmptinessCheck(AbstractValue v, boolean isEmpty) {
585+
Expr getAnEmptinessCheck(GuardValue v, boolean isEmpty) {
582586
result = this.getABooleanEmptinessCheck(v, isEmpty)
583587
}
584588
}
@@ -692,14 +696,14 @@ class GuardedExpr extends AccessOrCallExpr {
692696
* left-most qualifier, then so must the other (accessing the same SSA
693697
* variable).
694698
*/
695-
Guard getAGuard(Expr sub, AbstractValue v) { isGuardedByExpr(this, result, sub, v) }
699+
Guard getAGuard(Expr sub, GuardValue v) { isGuardedByExpr(this, result, sub, v) }
696700

697701
/**
698702
* Holds if this expression must have abstract value `v`. That is, this
699703
* expression is guarded by a structurally equal expression having abstract
700704
* value `v`.
701705
*/
702-
predicate mustHaveValue(AbstractValue v) {
706+
predicate mustHaveValue(GuardValue v) {
703707
exists(Guard g | g = this.getAGuard(g, v)) or ssaMustHaveValue(this, v)
704708
}
705709

@@ -713,7 +717,7 @@ class GuardedExpr extends AccessOrCallExpr {
713717
* variable).
714718
*/
715719
predicate isGuardedBy(Expr cond, Expr sub, boolean b) {
716-
cond = this.getAGuard(sub, any(BooleanValue v | v.getValue() = b))
720+
cond = this.getAGuard(sub, any(GuardValue v | v.asBooleanValue() = b))
717721
}
718722
}
719723

@@ -738,7 +742,7 @@ class GuardedExpr extends AccessOrCallExpr {
738742
class GuardedControlFlowNode extends ControlFlow::Nodes::ElementNode {
739743
private Guard g;
740744
private AccessOrCallExpr sub0;
741-
private AbstractValue v0;
745+
private GuardValue v0;
742746

743747
GuardedControlFlowNode() { g.controlsNode(this, sub0, v0) }
744748

@@ -753,7 +757,7 @@ class GuardedControlFlowNode extends ControlFlow::Nodes::ElementNode {
753757
* left-most qualifier, then so must the other (accessing the same SSA
754758
* variable).
755759
*/
756-
Guard getAGuard(Expr sub, AbstractValue v) {
760+
Guard getAGuard(Expr sub, GuardValue v) {
757761
result = g and
758762
sub = sub0 and
759763
v = v0
@@ -764,7 +768,7 @@ class GuardedControlFlowNode extends ControlFlow::Nodes::ElementNode {
764768
* control flow node is guarded by a structurally equal expression having
765769
* abstract value `v`.
766770
*/
767-
predicate mustHaveValue(AbstractValue v) { g = this.getAGuard(g, v) }
771+
predicate mustHaveValue(GuardValue v) { g = this.getAGuard(g, v) }
768772
}
769773

770774
/**
@@ -788,7 +792,7 @@ class GuardedControlFlowNode extends ControlFlow::Nodes::ElementNode {
788792
class GuardedDataFlowNode extends DataFlow::ExprNode {
789793
private Guard g;
790794
private AccessOrCallExpr sub0;
791-
private AbstractValue v0;
795+
private GuardValue v0;
792796

793797
GuardedDataFlowNode() {
794798
exists(ControlFlow::Nodes::ElementNode cfn | exists(this.getExprAtNode(cfn)) |
@@ -807,7 +811,7 @@ class GuardedDataFlowNode extends DataFlow::ExprNode {
807811
* left-most qualifier, then so must the other (accessing the same SSA
808812
* variable).
809813
*/
810-
Guard getAGuard(Expr sub, AbstractValue v) {
814+
Guard getAGuard(Expr sub, GuardValue v) {
811815
result = g and
812816
sub = sub0 and
813817
v = v0
@@ -818,17 +822,17 @@ class GuardedDataFlowNode extends DataFlow::ExprNode {
818822
* data flow node is guarded by a structurally equal expression having
819823
* abstract value `v`.
820824
*/
821-
predicate mustHaveValue(AbstractValue v) { g = this.getAGuard(g, v) }
825+
predicate mustHaveValue(GuardValue v) { g = this.getAGuard(g, v) }
822826
}
823827

824828
/** An expression guarded by a `null` check. */
825829
class NullGuardedExpr extends GuardedExpr {
826-
NullGuardedExpr() { this.mustHaveValue(any(NullValue v | v.isNonNull())) }
830+
NullGuardedExpr() { this.mustHaveValue(any(GuardValue v | v.isNonNullValue())) }
827831
}
828832

829833
/** A data flow node guarded by a `null` check. */
830834
class NullGuardedDataFlowNode extends GuardedDataFlowNode {
831-
NullGuardedDataFlowNode() { this.mustHaveValue(any(NullValue v | v.isNonNull())) }
835+
NullGuardedDataFlowNode() { this.mustHaveValue(any(GuardValue v | v.isNonNullValue())) }
832836
}
833837

834838
/** INTERNAL: Do not use. */
@@ -931,7 +935,7 @@ module Internal {
931935
bao.getAnOperand() = o and
932936
// The other operand must be provably non-null in order
933937
// for `only if` to hold
934-
o = any(NullValue nv | nv.isNonNull()).getAnExpr() and
938+
nonNullValueImplied(o) and
935939
e != o
936940
)
937941
}
@@ -973,7 +977,7 @@ module Internal {
973977
nonEmptyValue(def.getDefinition().getSource())
974978
}
975979

976-
deprecated predicate isGuard(Expr e, AbstractValue val) {
980+
deprecated predicate isGuard(Expr e, GuardValue val) {
977981
(
978982
e.getType() instanceof BoolType and
979983
not e instanceof BoolLiteral and
@@ -1207,7 +1211,7 @@ module Internal {
12071211
* Holds if basic block `bb` only is reached when guard `g` has abstract value `v`.
12081212
*/
12091213
cached
1210-
predicate guardControls(Guard g, BasicBlock bb, AbstractValue v) {
1214+
predicate guardControls(Guard g, BasicBlock bb, GuardValue v) {
12111215
g.(Guards::Guard).valueControls(bb, v)
12121216
}
12131217

@@ -1220,7 +1224,7 @@ module Internal {
12201224
pragma[nomagic]
12211225
private predicate nodeIsGuardedBySameSubExpr0(
12221226
ControlFlow::Node guardedCfn, BasicBlock guardedBB, AccessOrCallExpr guarded, Guard g,
1223-
AccessOrCallExpr sub, AbstractValue v
1227+
AccessOrCallExpr sub, GuardValue v
12241228
) {
12251229
Stages::GuardsStage::forceCachingInSameStage() and
12261230
guardedCfn = guarded.getAControlFlowNode() and
@@ -1233,7 +1237,7 @@ module Internal {
12331237
pragma[nomagic]
12341238
private predicate nodeIsGuardedBySameSubExpr(
12351239
ControlFlow::Node guardedCfn, BasicBlock guardedBB, AccessOrCallExpr guarded, Guard g,
1236-
AccessOrCallExpr sub, AbstractValue v
1240+
AccessOrCallExpr sub, GuardValue v
12371241
) {
12381242
nodeIsGuardedBySameSubExpr0(guardedCfn, guardedBB, guarded, g, sub, v) and
12391243
guardControlsSub(g, guardedBB, sub)
@@ -1242,7 +1246,7 @@ module Internal {
12421246
pragma[nomagic]
12431247
private predicate nodeIsGuardedBySameSubExprSsaDef0(
12441248
ControlFlow::Node cfn, BasicBlock guardedBB, AccessOrCallExpr guarded, Guard g,
1245-
ControlFlow::Node subCfn, BasicBlock subCfnBB, AccessOrCallExpr sub, AbstractValue v,
1249+
ControlFlow::Node subCfn, BasicBlock subCfnBB, AccessOrCallExpr sub, GuardValue v,
12461250
Ssa::Definition def
12471251
) {
12481252
nodeIsGuardedBySameSubExpr(cfn, guardedBB, guarded, g, sub, v) and
@@ -1253,7 +1257,7 @@ module Internal {
12531257
pragma[nomagic]
12541258
private predicate nodeIsGuardedBySameSubExprSsaDef(
12551259
ControlFlow::Node guardedCfn, AccessOrCallExpr guarded, Guard g, ControlFlow::Node subCfn,
1256-
AccessOrCallExpr sub, AbstractValue v, Ssa::Definition def
1260+
AccessOrCallExpr sub, GuardValue v, Ssa::Definition def
12571261
) {
12581262
exists(BasicBlock guardedBB, BasicBlock subCfnBB |
12591263
nodeIsGuardedBySameSubExprSsaDef0(guardedCfn, guardedBB, guarded, g, subCfn, subCfnBB, sub,
@@ -1264,17 +1268,15 @@ module Internal {
12641268

12651269
pragma[noinline]
12661270
private predicate isGuardedByExpr0(
1267-
AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
1271+
AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, GuardValue v
12681272
) {
12691273
forex(ControlFlow::Node cfn | cfn = guarded.getAControlFlowNode() |
12701274
nodeIsGuardedBySameSubExpr(cfn, _, guarded, g, sub, v)
12711275
)
12721276
}
12731277

12741278
cached
1275-
predicate isGuardedByExpr(
1276-
AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
1277-
) {
1279+
predicate isGuardedByExpr(AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, GuardValue v) {
12781280
isGuardedByExpr0(guarded, g, sub, v) and
12791281
forall(ControlFlow::Node subCfn, Ssa::Definition def |
12801282
nodeIsGuardedBySameSubExprSsaDef(_, guarded, g, subCfn, sub, v, def)
@@ -1285,7 +1287,7 @@ module Internal {
12851287

12861288
cached
12871289
predicate isGuardedByNode(
1288-
ControlFlow::Nodes::ElementNode guarded, Guard g, AccessOrCallExpr sub, AbstractValue v
1290+
ControlFlow::Nodes::ElementNode guarded, Guard g, AccessOrCallExpr sub, GuardValue v
12891291
) {
12901292
nodeIsGuardedBySameSubExpr(guarded, _, _, g, sub, v) and
12911293
forall(ControlFlow::Node subCfn, Ssa::Definition def |

csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import csharp
2121
private import ControlFlow
2222
private import internal.CallableReturns
2323
private import semmle.code.csharp.controlflow.Guards as G
24-
private import semmle.code.csharp.controlflow.Guards::AbstractValues
2524
private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl
2625
private import semmle.code.csharp.frameworks.System
2726
private import semmle.code.csharp.frameworks.Test
@@ -368,9 +367,9 @@ class Dereference extends G::DereferenceableExpr {
368367
(
369368
forex(Ssa::Definition def0 | this = def0.getARead() | this.isAlwaysNull0(def0))
370369
or
371-
exists(NullValue nv |
370+
exists(G::GuardValue nv |
372371
this.(G::GuardedExpr).mustHaveValue(nv) and
373-
nv.isNull()
372+
nv.isNullValue()
374373
)
375374
) and
376375
not this instanceof G::NullGuardedExpr

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ abstract class NonLocalJumpNode extends Node {
173173
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
174174
* the argument `x`.
175175
*/
176-
signature predicate guardChecksSig(Guard g, Expr e, AbstractValue v);
176+
signature predicate guardChecksSig(Guard g, Expr e, GuardValue v);
177177

178178
/**
179179
* Provides a set of barrier nodes for a guard that validates an expression.
@@ -190,7 +190,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
190190
SsaFlow::asNode(result) =
191191
SsaImpl::DataFlowIntegration::BarrierGuard<guardChecks/3>::getABarrierNode()
192192
or
193-
exists(Guard g, Expr e, AbstractValue v |
193+
exists(Guard g, Expr e, GuardValue v |
194194
guardChecks(g, e, v) and
195195
g.controlsNode(result.getControlFlowNode(), e, v)
196196
)

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -963,17 +963,17 @@ private module Cached {
963963
DataFlowIntegrationImpl::localMustFlowStep(v, nodeFrom, nodeTo)
964964
}
965965

966-
signature predicate guardChecksSig(Guards::Guard g, Expr e, Guards::AbstractValue v);
966+
signature predicate guardChecksSig(Guards::Guard g, Expr e, Guards::GuardValue v);
967967

968968
cached // nothing is actually cached
969969
module BarrierGuard<guardChecksSig/3 guardChecks> {
970970
private predicate guardChecksAdjTypes(
971971
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e,
972972
DataFlowIntegrationInput::GuardValue branch
973973
) {
974-
exists(Guards::AbstractValues::BooleanValue v |
974+
exists(Guards::GuardValue v |
975975
guardChecks(g, e.getAstNode(), v) and
976-
branch = v.getValue()
976+
branch = v.asBooleanValue()
977977
)
978978
}
979979

csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ private module Impl {
1010
private import semmle.code.csharp.controlflow.Guards as G
1111
private import ControlFlowReachability
1212

13-
private class BooleanValue = G::AbstractValues::BooleanValue;
14-
1513
private class ExprNode = ControlFlow::Nodes::ExprNode;
1614

1715
private class ExprChildReachability extends ControlFlowReachabilityConfiguration {
@@ -93,7 +91,7 @@ private module Impl {
9391
/**
9492
* Holds if basic block `bb` is guarded by this guard having value `v`.
9593
*/
96-
predicate controlsBasicBlock(ControlFlow::BasicBlock bb, G::AbstractValue v) {
94+
predicate controlsBasicBlock(ControlFlow::BasicBlock bb, G::GuardValue v) {
9795
super.controlsBasicBlock(bb, v)
9896
}
9997

@@ -130,7 +128,7 @@ private module Impl {
130128
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
131129
*/
132130
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
133-
exists(BooleanValue b | b.getValue() = testIsTrue |
131+
exists(G::GuardValue b | b.asBooleanValue() = testIsTrue |
134132
guard.controlsBasicBlock(controlled.(SsaReadPositionBlock).getBlock(), b)
135133
)
136134
}

0 commit comments

Comments
 (0)