Skip to content

Commit 8b85735

Browse files
committed
C++: Generalize predicates from booleans to abstract values.
1 parent aeb667c commit 8b85735

File tree

1 file changed

+31
-31
lines changed

1 file changed

+31
-31
lines changed

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

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,10 @@ class IRGuardCondition extends Instruction {
456456
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
457457
cached
458458
predicate comparesLt(Operand left, Operand right, int k, boolean isLessThan, boolean testIsTrue) {
459-
compares_lt(this, left, right, k, isLessThan, testIsTrue)
459+
exists(BooleanValue value |
460+
compares_lt(this, left, right, k, isLessThan, value) and
461+
value.getValue() = testIsTrue
462+
)
460463
}
461464

462465
/**
@@ -465,8 +468,8 @@ class IRGuardCondition extends Instruction {
465468
*/
466469
cached
467470
predicate ensuresLt(Operand left, Operand right, int k, IRBlock block, boolean isLessThan) {
468-
exists(boolean testIsTrue |
469-
compares_lt(this, left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
471+
exists(AbstractValue value |
472+
compares_lt(this, left, right, k, isLessThan, value) and this.valueControls(block, value)
470473
)
471474
}
472475

@@ -478,9 +481,9 @@ class IRGuardCondition extends Instruction {
478481
predicate ensuresLtEdge(
479482
Operand left, Operand right, int k, IRBlock pred, IRBlock succ, boolean isLessThan
480483
) {
481-
exists(boolean testIsTrue |
482-
compares_lt(this, left, right, k, isLessThan, testIsTrue) and
483-
this.controlsEdge(pred, succ, testIsTrue)
484+
exists(AbstractValue value |
485+
compares_lt(this, left, right, k, isLessThan, value) and
486+
this.valueControlsEdge(pred, succ, value)
484487
)
485488
}
486489

@@ -746,31 +749,28 @@ private predicate complex_eq(
746749

747750
/** Holds if `left < right + k` evaluates to `isLt` given that test is `testIsTrue`. */
748751
private predicate compares_lt(
749-
Instruction test, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
752+
Instruction test, Operand left, Operand right, int k, boolean isLt, AbstractValue value
750753
) {
751754
/* In the simple case, the test is the comparison, so isLt = testIsTrue */
752-
simple_comparison_lt(test, left, right, k) and isLt = true and testIsTrue = true
753-
or
754-
simple_comparison_lt(test, left, right, k) and isLt = false and testIsTrue = false
755+
simple_comparison_lt(test, left, right, k) and
756+
value.(BooleanValue).getValue() = isLt
755757
or
756-
complex_lt(test, left, right, k, isLt, testIsTrue)
758+
complex_lt(test, left, right, k, isLt, value)
757759
or
758760
/* (not (left < right + k)) => (left >= right + k) */
759-
exists(boolean isGe | isLt = isGe.booleanNot() |
760-
compares_ge(test, left, right, k, isGe, testIsTrue)
761-
)
761+
exists(boolean isGe | isLt = isGe.booleanNot() | compares_ge(test, left, right, k, isGe, value))
762762
or
763763
/* (x is true => (left < right + k)) => (!x is false => (left < right + k)) */
764-
exists(boolean isFalse | testIsTrue = isFalse.booleanNot() |
765-
compares_lt(test.(LogicalNotInstruction).getUnary(), left, right, k, isLt, isFalse)
764+
exists(AbstractValue dual | value = dual.getDualValue() |
765+
compares_lt(test.(LogicalNotInstruction).getUnary(), left, right, k, isLt, dual)
766766
)
767767
}
768768

769769
/** `(a < b + k) => (b > a - k) => (b >= a + (1-k))` */
770770
private predicate compares_ge(
771-
Instruction test, Operand left, Operand right, int k, boolean isGe, boolean testIsTrue
771+
Instruction test, Operand left, Operand right, int k, boolean isGe, AbstractValue value
772772
) {
773-
exists(int onemk | k = 1 - onemk | compares_lt(test, right, left, onemk, isGe, testIsTrue))
773+
exists(int onemk | k = 1 - onemk | compares_lt(test, right, left, onemk, isGe, value))
774774
}
775775

776776
/** Rearrange various simple comparisons into `left < right + k` form. */
@@ -797,41 +797,41 @@ private predicate simple_comparison_lt(CompareInstruction cmp, Operand left, Ope
797797
}
798798

799799
private predicate complex_lt(
800-
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
800+
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value
801801
) {
802-
sub_lt(cmp, left, right, k, isLt, testIsTrue)
802+
sub_lt(cmp, left, right, k, isLt, value)
803803
or
804-
add_lt(cmp, left, right, k, isLt, testIsTrue)
804+
add_lt(cmp, left, right, k, isLt, value)
805805
}
806806

807807
// left - x < right + c => left < right + (c+x)
808808
// left < (right - x) + c => left < right + (c-x)
809809
private predicate sub_lt(
810-
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
810+
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value
811811
) {
812812
exists(SubInstruction lhs, int c, int x |
813-
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
813+
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
814814
left = lhs.getLeftOperand() and
815815
x = int_value(lhs.getRight()) and
816816
k = c + x
817817
)
818818
or
819819
exists(SubInstruction rhs, int c, int x |
820-
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
820+
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
821821
right = rhs.getLeftOperand() and
822822
x = int_value(rhs.getRight()) and
823823
k = c - x
824824
)
825825
or
826826
exists(PointerSubInstruction lhs, int c, int x |
827-
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
827+
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
828828
left = lhs.getLeftOperand() and
829829
x = int_value(lhs.getRight()) and
830830
k = c + x
831831
)
832832
or
833833
exists(PointerSubInstruction rhs, int c, int x |
834-
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
834+
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
835835
right = rhs.getLeftOperand() and
836836
x = int_value(rhs.getRight()) and
837837
k = c - x
@@ -841,10 +841,10 @@ private predicate sub_lt(
841841
// left + x < right + c => left < right + (c-x)
842842
// left < (right + x) + c => left < right + (c+x)
843843
private predicate add_lt(
844-
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, boolean testIsTrue
844+
CompareInstruction cmp, Operand left, Operand right, int k, boolean isLt, AbstractValue value
845845
) {
846846
exists(AddInstruction lhs, int c, int x |
847-
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
847+
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
848848
(
849849
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
850850
or
@@ -854,7 +854,7 @@ private predicate add_lt(
854854
)
855855
or
856856
exists(AddInstruction rhs, int c, int x |
857-
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
857+
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
858858
(
859859
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
860860
or
@@ -864,7 +864,7 @@ private predicate add_lt(
864864
)
865865
or
866866
exists(PointerAddInstruction lhs, int c, int x |
867-
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
867+
compares_lt(cmp, lhs.getAUse(), right, c, isLt, value) and
868868
(
869869
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
870870
or
@@ -874,7 +874,7 @@ private predicate add_lt(
874874
)
875875
or
876876
exists(PointerAddInstruction rhs, int c, int x |
877-
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
877+
compares_lt(cmp, left, rhs.getAUse(), c, isLt, value) and
878878
(
879879
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
880880
or

0 commit comments

Comments
 (0)