Skip to content

Commit c8c7739

Browse files
committed
C++: Get rid of the trivial 'True' condition. Turns out it's not actually needed.
1 parent 656ff4a commit c8c7739

File tree

1 file changed

+32
-69
lines changed

1 file changed

+32
-69
lines changed

cpp/ql/src/semmle/code/cpp/controlflow/StackVariableReachability.qll

Lines changed: 32 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
private import semmle.code.cpp.controlflow.Guards
77
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
88

9-
private newtype TCondition =
10-
TTrue() or
11-
TLogicalCondition(LogicalGuardCondition guard, boolean testIsTrue) { testIsTrue = [false, true] }
12-
139
/** A `GuardCondition` which appear in a control-flow path to a sink. */
1410
abstract private class LogicalGuardCondition extends GuardCondition {
1511
LogicalGuardCondition() {
@@ -65,84 +61,58 @@ private class NotGuardCondition extends LogicalGuardCondition, NotExpr {
6561
}
6662
}
6763

68-
/** A condition that either the trivial `True` condition, or a complex `LogicalCondition`. */
69-
abstract private class Condition extends TCondition {
70-
abstract string toString();
64+
private newtype TCondition =
65+
MkCondition(LogicalGuardCondition guard, boolean testIsTrue) { testIsTrue = [false, true] }
66+
67+
private class Condition extends MkCondition {
68+
boolean testIsTrue;
69+
LogicalGuardCondition guard;
70+
71+
Condition() { this = MkCondition(guard, testIsTrue) }
7172

7273
/**
7374
* Holds if this condition having the value `this.getTruthValue()` implies that `cond` has truth
7475
* value `cond.getTruthValue()`.
7576
*/
76-
pragma[nomagic]
77-
abstract predicate impliesCondition(Condition cond);
77+
string toString() { result = guard.toString() + " == " + testIsTrue.toString() }
7878

7979
/** Gets the value of this `Condition`. */
80-
abstract boolean getTruthValue();
81-
82-
/** Gets the negated expression represented by this `Condition`, if any. */
83-
Condition negate() { none() }
84-
85-
/**
86-
* Holds if this condition having the value `this.getTruthValue()` implies that `cond` cannot have
87-
* the truth value `cond.getTruthValue()`.
88-
*/
89-
final predicate refutesCondition(Condition cond) { this.impliesCondition(cond.negate()) }
90-
91-
/** Gets the `Location` of the expression that generated this `Condition`, if any. */
92-
Location getLocation() { none() }
93-
}
94-
95-
private class True extends Condition, TTrue {
96-
True() { this = TTrue() }
97-
98-
override string toString() { result = "True" }
99-
100-
override boolean getTruthValue() { result = true }
101-
102-
override predicate impliesCondition(Condition cond) { cond instanceof True }
103-
}
104-
105-
private class LogicalCondition extends Condition, TLogicalCondition {
106-
boolean testIsTrue;
107-
LogicalGuardCondition guard;
108-
109-
LogicalCondition() { this = TLogicalCondition(guard, testIsTrue) }
110-
111-
override string toString() { result = guard.toString() + " == " + testIsTrue.toString() }
112-
113-
override boolean getTruthValue() { result = testIsTrue }
80+
boolean getTruthValue() { result = testIsTrue }
11481

11582
LogicalGuardCondition getCondition() { result = guard }
11683

117-
override predicate impliesCondition(Condition cond) {
118-
cond instanceof True
119-
or
84+
pragma[nomagic]
85+
predicate impliesCondition(Condition cond) {
12086
exists(LogicalGuardCondition other |
121-
other = cond.(LogicalCondition).getCondition() and
87+
other = cond.getCondition() and
12288
this.getCondition()
12389
.impliesCondition(globalValueNumber(other).getAnExpr(),
12490
pragma[only_bind_into](pragma[only_bind_out](testIsTrue)),
12591
pragma[only_bind_into](pragma[only_bind_out](cond.getTruthValue())))
12692
)
12793
}
12894

129-
override LogicalCondition negate() {
95+
/** Gets the negated expression represented by this `Condition`, if any. */
96+
private Condition negate() {
13097
result.getCondition() = guard and
13198
result.getTruthValue() = testIsTrue.booleanNot()
13299
}
133100

134-
override Location getLocation() { result = guard.getLocation() }
101+
/**
102+
* Holds if this condition having the value `this.getTruthValue()` implies that `cond` cannot have
103+
* the truth value `cond.getTruthValue()`.
104+
*/
105+
final predicate refutesCondition(Condition cond) { this.impliesCondition(cond.negate()) }
106+
107+
/** Gets the `Location` of the expression that generated this `Condition`. */
108+
Location getLocation() { result = guard.getLocation() }
135109
}
136110

137111
/**
138-
* Gets a `Condition` that controls `b`.
139-
*
140-
* Note: The trivial `True` condition always controls `b`.
112+
* Gets a `Condition` that controls `b`. That is, to enter `b` the condition must hold.
141113
*/
142114
private Condition getADirectCondition(BasicBlock b) {
143-
result instanceof True
144-
or
145-
result.(LogicalCondition).getCondition().controls(b, result.(LogicalCondition).getTruthValue())
115+
result.getCondition().controls(b, result.getTruthValue())
146116
}
147117

148118
/**
@@ -365,20 +335,14 @@ abstract class StackVariableReachability extends string {
365335
private Condition getASinkCondition(SemanticStackVariable v) {
366336
exists(BasicBlock bb |
367337
revBbEntryReachesLocally(bb, v, _, this) and
368-
result
369-
.(LogicalCondition)
370-
.getCondition()
371-
.controls(bb, result.(LogicalCondition).getTruthValue())
338+
result.getCondition().controls(bb, result.getTruthValue())
372339
)
373340
}
374341

375342
private Condition getABarrierCondition(SemanticStackVariable v) {
376343
exists(BasicBlock bb |
377344
isBarrier(bb.getANode(), v) and
378-
result
379-
.(LogicalCondition)
380-
.getCondition()
381-
.controls(bb, result.(LogicalCondition).getTruthValue())
345+
result.getCondition().controls(bb, result.getTruthValue())
382346
)
383347
}
384348

@@ -409,12 +373,11 @@ abstract class StackVariableReachability extends string {
409373
)
410374
)
411375
or
412-
exists(BasicBlock pred, LogicalCondition cond |
376+
exists(BasicBlock pred |
413377
pred.getASuccessor() = bb and
414-
cond = getACondition(source, v, pred) and
378+
result = getACondition(source, v, pred) and
415379
revBbSuccessorEntryReaches0(source, pred, v, _, this) and
416-
result = cond and
417-
exists(LogicalGuardCondition c | c = cond.getCondition() |
380+
exists(LogicalGuardCondition c | c = result.getCondition() |
418381
not isLoopCondition(c, pred, bb) and
419382
not isDisjunctionCondition(c, pred, bb) and
420383
not isLoopVariantCondition(c, pred, bb)
@@ -451,14 +414,14 @@ abstract class StackVariableReachability extends string {
451414
// another path condition that refutes that the condition is true.
452415
succ = pred.getATrueSuccessor() and
453416
not exists(Condition cond | cond = getACondition(source, v, pred) |
454-
cond.refutesCondition(TLogicalCondition(pred.getEnd(), true))
417+
cond.refutesCondition(MkCondition(pred.getEnd(), true))
455418
)
456419
or
457420
// If we picked the successor edge corresponding to a condition being false, there must not be
458421
// another path condition that refutes that the condition is false.
459422
succ = pred.getAFalseSuccessor() and
460423
not exists(Condition cond | cond = getACondition(source, v, pred) |
461-
cond.refutesCondition(TLogicalCondition(pred.getEnd(), false))
424+
cond.refutesCondition(MkCondition(pred.getEnd(), false))
462425
)
463426
or
464427
// If it wasn't a conditional successor edge we require nothing.

0 commit comments

Comments
 (0)