|
6 | 6 | private import semmle.code.cpp.controlflow.Guards
|
7 | 7 | private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
8 | 8 |
|
9 |
| -private newtype TCondition = |
10 |
| - TTrue() or |
11 |
| - TLogicalCondition(LogicalGuardCondition guard, boolean testIsTrue) { testIsTrue = [false, true] } |
12 |
| - |
13 | 9 | /** A `GuardCondition` which appear in a control-flow path to a sink. */
|
14 | 10 | abstract private class LogicalGuardCondition extends GuardCondition {
|
15 | 11 | LogicalGuardCondition() {
|
@@ -65,84 +61,58 @@ private class NotGuardCondition extends LogicalGuardCondition, NotExpr {
|
65 | 61 | }
|
66 | 62 | }
|
67 | 63 |
|
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) } |
71 | 72 |
|
72 | 73 | /**
|
73 | 74 | * Holds if this condition having the value `this.getTruthValue()` implies that `cond` has truth
|
74 | 75 | * value `cond.getTruthValue()`.
|
75 | 76 | */
|
76 |
| - pragma[nomagic] |
77 |
| - abstract predicate impliesCondition(Condition cond); |
| 77 | + string toString() { result = guard.toString() + " == " + testIsTrue.toString() } |
78 | 78 |
|
79 | 79 | /** 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 } |
114 | 81 |
|
115 | 82 | LogicalGuardCondition getCondition() { result = guard }
|
116 | 83 |
|
117 |
| - override predicate impliesCondition(Condition cond) { |
118 |
| - cond instanceof True |
119 |
| - or |
| 84 | + pragma[nomagic] |
| 85 | + predicate impliesCondition(Condition cond) { |
120 | 86 | exists(LogicalGuardCondition other |
|
121 |
| - other = cond.(LogicalCondition).getCondition() and |
| 87 | + other = cond.getCondition() and |
122 | 88 | this.getCondition()
|
123 | 89 | .impliesCondition(globalValueNumber(other).getAnExpr(),
|
124 | 90 | pragma[only_bind_into](pragma[only_bind_out](testIsTrue)),
|
125 | 91 | pragma[only_bind_into](pragma[only_bind_out](cond.getTruthValue())))
|
126 | 92 | )
|
127 | 93 | }
|
128 | 94 |
|
129 |
| - override LogicalCondition negate() { |
| 95 | + /** Gets the negated expression represented by this `Condition`, if any. */ |
| 96 | + private Condition negate() { |
130 | 97 | result.getCondition() = guard and
|
131 | 98 | result.getTruthValue() = testIsTrue.booleanNot()
|
132 | 99 | }
|
133 | 100 |
|
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() } |
135 | 109 | }
|
136 | 110 |
|
137 | 111 | /**
|
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. |
141 | 113 | */
|
142 | 114 | 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()) |
146 | 116 | }
|
147 | 117 |
|
148 | 118 | /**
|
@@ -365,20 +335,14 @@ abstract class StackVariableReachability extends string {
|
365 | 335 | private Condition getASinkCondition(SemanticStackVariable v) {
|
366 | 336 | exists(BasicBlock bb |
|
367 | 337 | revBbEntryReachesLocally(bb, v, _, this) and
|
368 |
| - result |
369 |
| - .(LogicalCondition) |
370 |
| - .getCondition() |
371 |
| - .controls(bb, result.(LogicalCondition).getTruthValue()) |
| 338 | + result.getCondition().controls(bb, result.getTruthValue()) |
372 | 339 | )
|
373 | 340 | }
|
374 | 341 |
|
375 | 342 | private Condition getABarrierCondition(SemanticStackVariable v) {
|
376 | 343 | exists(BasicBlock bb |
|
377 | 344 | isBarrier(bb.getANode(), v) and
|
378 |
| - result |
379 |
| - .(LogicalCondition) |
380 |
| - .getCondition() |
381 |
| - .controls(bb, result.(LogicalCondition).getTruthValue()) |
| 345 | + result.getCondition().controls(bb, result.getTruthValue()) |
382 | 346 | )
|
383 | 347 | }
|
384 | 348 |
|
@@ -409,12 +373,11 @@ abstract class StackVariableReachability extends string {
|
409 | 373 | )
|
410 | 374 | )
|
411 | 375 | or
|
412 |
| - exists(BasicBlock pred, LogicalCondition cond | |
| 376 | + exists(BasicBlock pred | |
413 | 377 | pred.getASuccessor() = bb and
|
414 |
| - cond = getACondition(source, v, pred) and |
| 378 | + result = getACondition(source, v, pred) and |
415 | 379 | revBbSuccessorEntryReaches0(source, pred, v, _, this) and
|
416 |
| - result = cond and |
417 |
| - exists(LogicalGuardCondition c | c = cond.getCondition() | |
| 380 | + exists(LogicalGuardCondition c | c = result.getCondition() | |
418 | 381 | not isLoopCondition(c, pred, bb) and
|
419 | 382 | not isDisjunctionCondition(c, pred, bb) and
|
420 | 383 | not isLoopVariantCondition(c, pred, bb)
|
@@ -451,14 +414,14 @@ abstract class StackVariableReachability extends string {
|
451 | 414 | // another path condition that refutes that the condition is true.
|
452 | 415 | succ = pred.getATrueSuccessor() and
|
453 | 416 | not exists(Condition cond | cond = getACondition(source, v, pred) |
|
454 |
| - cond.refutesCondition(TLogicalCondition(pred.getEnd(), true)) |
| 417 | + cond.refutesCondition(MkCondition(pred.getEnd(), true)) |
455 | 418 | )
|
456 | 419 | or
|
457 | 420 | // If we picked the successor edge corresponding to a condition being false, there must not be
|
458 | 421 | // another path condition that refutes that the condition is false.
|
459 | 422 | succ = pred.getAFalseSuccessor() and
|
460 | 423 | not exists(Condition cond | cond = getACondition(source, v, pred) |
|
461 |
| - cond.refutesCondition(TLogicalCondition(pred.getEnd(), false)) |
| 424 | + cond.refutesCondition(MkCondition(pred.getEnd(), false)) |
462 | 425 | )
|
463 | 426 | or
|
464 | 427 | // If it wasn't a conditional successor edge we require nothing.
|
|
0 commit comments