Skip to content

Commit b7292fb

Browse files
committed
C++: Introduce 'AbstractValue' similar to what C# has.
1 parent 2af68d3 commit b7292fb

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,44 @@ private predicate isUnreachedBlock(IRBlock block) {
2020
block.getFirstInstruction() instanceof UnreachedInstruction
2121
}
2222

23+
private newtype TAbstractValue =
24+
TBooleanValue(boolean b) { b = true or b = false } or
25+
TMatchValue(CaseEdge c)
26+
27+
/**
28+
* An abstract value. This is either a boolean value, or a `switch` case.
29+
*/
30+
abstract class AbstractValue extends TAbstractValue {
31+
/** Gets an abstract value that represents the dual of this value, if any. */
32+
abstract AbstractValue getDualValue();
33+
34+
/** Gets a textual representation of this abstract value. */
35+
abstract string toString();
36+
}
37+
38+
/** A Boolean value. */
39+
class BooleanValue extends AbstractValue, TBooleanValue {
40+
/** Gets the underlying Boolean value. */
41+
boolean getValue() { this = TBooleanValue(result) }
42+
43+
override BooleanValue getDualValue() { result.getValue() = this.getValue().booleanNot() }
44+
45+
override string toString() { result = this.getValue().toString() }
46+
}
47+
48+
/** A value that represents a match against a specific `switch` case. */
49+
class MatchValue extends AbstractValue, TMatchValue {
50+
/** Gets the case. */
51+
CaseEdge getCase() { this = TMatchValue(result) }
52+
53+
override MatchValue getDualValue() {
54+
// A `MatchValue` has no dual.
55+
none()
56+
}
57+
58+
override string toString() { result = this.getCase().toString() }
59+
}
60+
2361
/**
2462
* A Boolean condition in the AST that guards one or more basic blocks. This includes
2563
* operands of logical operators but not switch statements.

0 commit comments

Comments
 (0)