Skip to content

Commit a826c83

Browse files
authored
Merge pull request github#13682 from jketema/ptr-comp
C++: Support pointer addition and subtraction in the IRGuards library
2 parents 4920557 + 2c2903d commit a826c83

File tree

4 files changed

+200
-0
lines changed

4 files changed

+200
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `IRGuards` library has improved handling of pointer addition and subtraction operations.

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,20 @@ private predicate sub_lt(
627627
x = int_value(rhs.getRight()) and
628628
k = c - x
629629
)
630+
or
631+
exists(PointerSubInstruction lhs, int c, int x |
632+
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
633+
left = lhs.getLeftOperand() and
634+
x = int_value(lhs.getRight()) and
635+
k = c + x
636+
)
637+
or
638+
exists(PointerSubInstruction rhs, int c, int x |
639+
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
640+
right = rhs.getLeftOperand() and
641+
x = int_value(rhs.getRight()) and
642+
k = c - x
643+
)
630644
}
631645

632646
// left + x < right + c => left < right + (c-x)
@@ -653,6 +667,26 @@ private predicate add_lt(
653667
) and
654668
k = c + x
655669
)
670+
or
671+
exists(PointerAddInstruction lhs, int c, int x |
672+
compares_lt(cmp, lhs.getAUse(), right, c, isLt, testIsTrue) and
673+
(
674+
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
675+
or
676+
left = lhs.getRightOperand() and x = int_value(lhs.getLeft())
677+
) and
678+
k = c - x
679+
)
680+
or
681+
exists(PointerAddInstruction rhs, int c, int x |
682+
compares_lt(cmp, left, rhs.getAUse(), c, isLt, testIsTrue) and
683+
(
684+
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
685+
or
686+
right = rhs.getRightOperand() and x = int_value(rhs.getLeft())
687+
) and
688+
k = c + x
689+
)
656690
}
657691

658692
// left - x == right + c => left == right + (c+x)
@@ -673,6 +707,20 @@ private predicate sub_eq(
673707
x = int_value(rhs.getRight()) and
674708
k = c - x
675709
)
710+
or
711+
exists(PointerSubInstruction lhs, int c, int x |
712+
compares_eq(cmp, lhs.getAUse(), right, c, areEqual, testIsTrue) and
713+
left = lhs.getLeftOperand() and
714+
x = int_value(lhs.getRight()) and
715+
k = c + x
716+
)
717+
or
718+
exists(PointerSubInstruction rhs, int c, int x |
719+
compares_eq(cmp, left, rhs.getAUse(), c, areEqual, testIsTrue) and
720+
right = rhs.getLeftOperand() and
721+
x = int_value(rhs.getRight()) and
722+
k = c - x
723+
)
676724
}
677725

678726
// left + x == right + c => left == right + (c-x)
@@ -699,6 +747,26 @@ private predicate add_eq(
699747
) and
700748
k = c + x
701749
)
750+
or
751+
exists(PointerAddInstruction lhs, int c, int x |
752+
compares_eq(cmp, lhs.getAUse(), right, c, areEqual, testIsTrue) and
753+
(
754+
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
755+
or
756+
left = lhs.getRightOperand() and x = int_value(lhs.getLeft())
757+
) and
758+
k = c - x
759+
)
760+
or
761+
exists(PointerAddInstruction rhs, int c, int x |
762+
compares_eq(cmp, left, rhs.getAUse(), c, areEqual, testIsTrue) and
763+
(
764+
right = rhs.getLeftOperand() and x = int_value(rhs.getRight())
765+
or
766+
right = rhs.getRightOperand() and x = int_value(rhs.getLeft())
767+
) and
768+
k = c + x
769+
)
702770
}
703771

704772
/** The int value of integer constant expression. */

cpp/ql/test/library-tests/controlflow/guards-ir/test.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,19 @@ void test5(int x) {
151151
void test6(int x, int y) {
152152
return x && y;
153153
}
154+
155+
int ptr_test(int *x, int *y) {
156+
if (x == y + 42) {
157+
}
158+
159+
if (x == y - 42) {
160+
}
161+
162+
if (x < y + 42) {
163+
}
164+
165+
if (x < y - 42) {
166+
}
167+
168+
return 0;
169+
}

cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ astGuards
3030
| test.c:152:10:152:10 | x |
3131
| test.c:152:10:152:15 | ... && ... |
3232
| test.c:152:15:152:15 | y |
33+
| test.c:156:9:156:19 | ... == ... |
34+
| test.c:159:9:159:19 | ... == ... |
35+
| test.c:162:9:162:18 | ... < ... |
36+
| test.c:165:9:165:18 | ... < ... |
3337
| test.cpp:18:8:18:10 | call to get |
3438
| test.cpp:31:7:31:13 | ... == ... |
3539
| test.cpp:42:13:42:20 | call to getABool |
@@ -122,6 +126,38 @@ astGuardsCompare
122126
| 109 | y < 0+0 when ... < ... is true |
123127
| 109 | y >= 0+0 when ... < ... is false |
124128
| 109 | y >= 0+0 when ... \|\| ... is false |
129+
| 156 | ... + ... != x+0 when ... == ... is false |
130+
| 156 | ... + ... == x+0 when ... == ... is true |
131+
| 156 | x != ... + ...+0 when ... == ... is false |
132+
| 156 | x != y+42 when ... == ... is false |
133+
| 156 | x == ... + ...+0 when ... == ... is true |
134+
| 156 | x == y+42 when ... == ... is true |
135+
| 156 | y != x+-42 when ... == ... is false |
136+
| 156 | y == x+-42 when ... == ... is true |
137+
| 159 | ... - ... != x+0 when ... == ... is false |
138+
| 159 | ... - ... == x+0 when ... == ... is true |
139+
| 159 | x != ... - ...+0 when ... == ... is false |
140+
| 159 | x != y+-42 when ... == ... is false |
141+
| 159 | x == ... - ...+0 when ... == ... is true |
142+
| 159 | x == y+-42 when ... == ... is true |
143+
| 159 | y != x+42 when ... == ... is false |
144+
| 159 | y == x+42 when ... == ... is true |
145+
| 162 | ... + ... < x+1 when ... < ... is false |
146+
| 162 | ... + ... >= x+1 when ... < ... is true |
147+
| 162 | x < ... + ...+0 when ... < ... is true |
148+
| 162 | x < y+42 when ... < ... is true |
149+
| 162 | x >= ... + ...+0 when ... < ... is false |
150+
| 162 | x >= y+42 when ... < ... is false |
151+
| 162 | y < x+-41 when ... < ... is false |
152+
| 162 | y >= x+-41 when ... < ... is true |
153+
| 165 | ... - ... < x+1 when ... < ... is false |
154+
| 165 | ... - ... >= x+1 when ... < ... is true |
155+
| 165 | x < ... - ...+0 when ... < ... is true |
156+
| 165 | x < y+-42 when ... < ... is true |
157+
| 165 | x >= ... - ...+0 when ... < ... is false |
158+
| 165 | x >= y+-42 when ... < ... is false |
159+
| 165 | y < x+43 when ... < ... is false |
160+
| 165 | y >= x+43 when ... < ... is true |
125161
astGuardsControl
126162
| test.c:7:9:7:13 | ... > ... | false | 10 | 11 |
127163
| test.c:7:9:7:13 | ... > ... | true | 7 | 9 |
@@ -208,6 +244,10 @@ astGuardsControl
208244
| test.c:152:10:152:10 | x | true | 152 | 152 |
209245
| test.c:152:10:152:15 | ... && ... | true | 151 | 152 |
210246
| test.c:152:15:152:15 | y | true | 151 | 152 |
247+
| test.c:156:9:156:19 | ... == ... | true | 156 | 157 |
248+
| test.c:159:9:159:19 | ... == ... | true | 159 | 160 |
249+
| test.c:162:9:162:18 | ... < ... | true | 162 | 163 |
250+
| test.c:165:9:165:18 | ... < ... | true | 165 | 166 |
211251
| test.cpp:18:8:18:10 | call to get | true | 19 | 19 |
212252
| test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 |
213253
| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 |
@@ -364,6 +404,22 @@ astGuardsEnsure
364404
| test.c:109:9:109:23 | ... \|\| ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | 113 | 113 |
365405
| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | test.c:109:23:109:23 | 0 | 0 | 113 | 113 |
366406
| test.c:109:19:109:23 | ... < ... | test.c:109:23:109:23 | 0 | < | test.c:109:19:109:19 | y | 1 | 113 | 113 |
407+
| test.c:156:9:156:19 | ... == ... | test.c:156:9:156:9 | x | == | test.c:156:14:156:14 | y | 42 | 156 | 157 |
408+
| test.c:156:9:156:19 | ... == ... | test.c:156:9:156:9 | x | == | test.c:156:14:156:19 | ... + ... | 0 | 156 | 157 |
409+
| test.c:156:9:156:19 | ... == ... | test.c:156:14:156:14 | y | == | test.c:156:9:156:9 | x | -42 | 156 | 157 |
410+
| test.c:156:9:156:19 | ... == ... | test.c:156:14:156:19 | ... + ... | == | test.c:156:9:156:9 | x | 0 | 156 | 157 |
411+
| test.c:159:9:159:19 | ... == ... | test.c:159:9:159:9 | x | == | test.c:159:14:159:14 | y | -42 | 159 | 160 |
412+
| test.c:159:9:159:19 | ... == ... | test.c:159:9:159:9 | x | == | test.c:159:14:159:19 | ... - ... | 0 | 159 | 160 |
413+
| test.c:159:9:159:19 | ... == ... | test.c:159:14:159:14 | y | == | test.c:159:9:159:9 | x | 42 | 159 | 160 |
414+
| test.c:159:9:159:19 | ... == ... | test.c:159:14:159:19 | ... - ... | == | test.c:159:9:159:9 | x | 0 | 159 | 160 |
415+
| test.c:162:9:162:18 | ... < ... | test.c:162:9:162:9 | x | < | test.c:162:13:162:13 | y | 42 | 162 | 163 |
416+
| test.c:162:9:162:18 | ... < ... | test.c:162:9:162:9 | x | < | test.c:162:13:162:18 | ... + ... | 0 | 162 | 163 |
417+
| test.c:162:9:162:18 | ... < ... | test.c:162:13:162:13 | y | >= | test.c:162:9:162:9 | x | -41 | 162 | 163 |
418+
| test.c:162:9:162:18 | ... < ... | test.c:162:13:162:18 | ... + ... | >= | test.c:162:9:162:9 | x | 1 | 162 | 163 |
419+
| test.c:165:9:165:18 | ... < ... | test.c:165:9:165:9 | x | < | test.c:165:13:165:13 | y | -42 | 165 | 166 |
420+
| test.c:165:9:165:18 | ... < ... | test.c:165:9:165:9 | x | < | test.c:165:13:165:18 | ... - ... | 0 | 165 | 166 |
421+
| test.c:165:9:165:18 | ... < ... | test.c:165:13:165:13 | y | >= | test.c:165:9:165:9 | x | 43 | 165 | 166 |
422+
| test.c:165:9:165:18 | ... < ... | test.c:165:13:165:18 | ... - ... | >= | test.c:165:9:165:9 | x | 1 | 165 | 166 |
367423
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 |
368424
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 34 | 34 |
369425
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 |
@@ -397,6 +453,10 @@ irGuards
397453
| test.c:146:8:146:8 | Load: x |
398454
| test.c:152:10:152:10 | Load: x |
399455
| test.c:152:15:152:15 | Load: y |
456+
| test.c:156:9:156:19 | CompareEQ: ... == ... |
457+
| test.c:159:9:159:19 | CompareEQ: ... == ... |
458+
| test.c:162:9:162:18 | CompareLT: ... < ... |
459+
| test.c:165:9:165:18 | CompareLT: ... < ... |
400460
| test.cpp:18:8:18:12 | CompareNE: (bool)... |
401461
| test.cpp:31:7:31:13 | CompareEQ: ... == ... |
402462
| test.cpp:42:13:42:20 | Call: call to getABool |
@@ -473,6 +533,38 @@ irGuardsCompare
473533
| 109 | x == 0+0 when CompareEQ: ... == ... is true |
474534
| 109 | y < 0+0 when CompareLT: ... < ... is true |
475535
| 109 | y >= 0+0 when CompareLT: ... < ... is false |
536+
| 156 | ... + ... != x+0 when CompareEQ: ... == ... is false |
537+
| 156 | ... + ... == x+0 when CompareEQ: ... == ... is true |
538+
| 156 | x != ... + ...+0 when CompareEQ: ... == ... is false |
539+
| 156 | x != y+42 when CompareEQ: ... == ... is false |
540+
| 156 | x == ... + ...+0 when CompareEQ: ... == ... is true |
541+
| 156 | x == y+42 when CompareEQ: ... == ... is true |
542+
| 156 | y != x+-42 when CompareEQ: ... == ... is false |
543+
| 156 | y == x+-42 when CompareEQ: ... == ... is true |
544+
| 159 | ... - ... != x+0 when CompareEQ: ... == ... is false |
545+
| 159 | ... - ... == x+0 when CompareEQ: ... == ... is true |
546+
| 159 | x != ... - ...+0 when CompareEQ: ... == ... is false |
547+
| 159 | x != y+-42 when CompareEQ: ... == ... is false |
548+
| 159 | x == ... - ...+0 when CompareEQ: ... == ... is true |
549+
| 159 | x == y+-42 when CompareEQ: ... == ... is true |
550+
| 159 | y != x+42 when CompareEQ: ... == ... is false |
551+
| 159 | y == x+42 when CompareEQ: ... == ... is true |
552+
| 162 | ... + ... < x+1 when CompareLT: ... < ... is false |
553+
| 162 | ... + ... >= x+1 when CompareLT: ... < ... is true |
554+
| 162 | x < ... + ...+0 when CompareLT: ... < ... is true |
555+
| 162 | x < y+42 when CompareLT: ... < ... is true |
556+
| 162 | x >= ... + ...+0 when CompareLT: ... < ... is false |
557+
| 162 | x >= y+42 when CompareLT: ... < ... is false |
558+
| 162 | y < x+-41 when CompareLT: ... < ... is false |
559+
| 162 | y >= x+-41 when CompareLT: ... < ... is true |
560+
| 165 | ... - ... < x+1 when CompareLT: ... < ... is false |
561+
| 165 | ... - ... >= x+1 when CompareLT: ... < ... is true |
562+
| 165 | x < ... - ...+0 when CompareLT: ... < ... is true |
563+
| 165 | x < y+-42 when CompareLT: ... < ... is true |
564+
| 165 | x >= ... - ...+0 when CompareLT: ... < ... is false |
565+
| 165 | x >= y+-42 when CompareLT: ... < ... is false |
566+
| 165 | y < x+43 when CompareLT: ... < ... is false |
567+
| 165 | y >= x+43 when CompareLT: ... < ... is true |
476568
irGuardsControl
477569
| test.c:7:9:7:13 | CompareGT: ... > ... | false | 11 | 11 |
478570
| test.c:7:9:7:13 | CompareGT: ... > ... | true | 8 | 8 |
@@ -551,6 +643,10 @@ irGuardsControl
551643
| test.c:146:8:146:8 | Load: x | false | 147 | 147 |
552644
| test.c:152:10:152:10 | Load: x | true | 152 | 152 |
553645
| test.c:152:15:152:15 | Load: y | true | 152 | 152 |
646+
| test.c:156:9:156:19 | CompareEQ: ... == ... | true | 156 | 157 |
647+
| test.c:159:9:159:19 | CompareEQ: ... == ... | true | 159 | 160 |
648+
| test.c:162:9:162:18 | CompareLT: ... < ... | true | 162 | 163 |
649+
| test.c:165:9:165:18 | CompareLT: ... < ... | true | 165 | 166 |
554650
| test.cpp:18:8:18:12 | CompareNE: (bool)... | true | 19 | 19 |
555651
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | false | 34 | 34 |
556652
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | true | 30 | 30 |
@@ -690,6 +786,22 @@ irGuardsEnsure
690786
| test.c:109:9:109:14 | CompareEQ: ... == ... | test.c:109:14:109:14 | Constant: 0 | != | test.c:109:9:109:9 | Load: x | 0 | 113 | 113 |
691787
| test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:19:109:19 | Load: y | >= | test.c:109:23:109:23 | Constant: (long)... | 0 | 113 | 113 |
692788
| test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:23:109:23 | Constant: (long)... | < | test.c:109:19:109:19 | Load: y | 1 | 113 | 113 |
789+
| test.c:156:9:156:19 | CompareEQ: ... == ... | test.c:156:9:156:9 | Load: x | == | test.c:156:14:156:14 | Load: y | 42 | 156 | 157 |
790+
| test.c:156:9:156:19 | CompareEQ: ... == ... | test.c:156:9:156:9 | Load: x | == | test.c:156:14:156:19 | PointerAdd: ... + ... | 0 | 156 | 157 |
791+
| test.c:156:9:156:19 | CompareEQ: ... == ... | test.c:156:14:156:14 | Load: y | == | test.c:156:9:156:9 | Load: x | -42 | 156 | 157 |
792+
| test.c:156:9:156:19 | CompareEQ: ... == ... | test.c:156:14:156:19 | PointerAdd: ... + ... | == | test.c:156:9:156:9 | Load: x | 0 | 156 | 157 |
793+
| test.c:159:9:159:19 | CompareEQ: ... == ... | test.c:159:9:159:9 | Load: x | == | test.c:159:14:159:14 | Load: y | -42 | 159 | 160 |
794+
| test.c:159:9:159:19 | CompareEQ: ... == ... | test.c:159:9:159:9 | Load: x | == | test.c:159:14:159:19 | PointerSub: ... - ... | 0 | 159 | 160 |
795+
| test.c:159:9:159:19 | CompareEQ: ... == ... | test.c:159:14:159:14 | Load: y | == | test.c:159:9:159:9 | Load: x | 42 | 159 | 160 |
796+
| test.c:159:9:159:19 | CompareEQ: ... == ... | test.c:159:14:159:19 | PointerSub: ... - ... | == | test.c:159:9:159:9 | Load: x | 0 | 159 | 160 |
797+
| test.c:162:9:162:18 | CompareLT: ... < ... | test.c:162:9:162:9 | Load: x | < | test.c:162:13:162:13 | Load: y | 42 | 162 | 163 |
798+
| test.c:162:9:162:18 | CompareLT: ... < ... | test.c:162:9:162:9 | Load: x | < | test.c:162:13:162:18 | PointerAdd: ... + ... | 0 | 162 | 163 |
799+
| test.c:162:9:162:18 | CompareLT: ... < ... | test.c:162:13:162:13 | Load: y | >= | test.c:162:9:162:9 | Load: x | -41 | 162 | 163 |
800+
| test.c:162:9:162:18 | CompareLT: ... < ... | test.c:162:13:162:18 | PointerAdd: ... + ... | >= | test.c:162:9:162:9 | Load: x | 1 | 162 | 163 |
801+
| test.c:165:9:165:18 | CompareLT: ... < ... | test.c:165:9:165:9 | Load: x | < | test.c:165:13:165:13 | Load: y | -42 | 165 | 166 |
802+
| test.c:165:9:165:18 | CompareLT: ... < ... | test.c:165:9:165:9 | Load: x | < | test.c:165:13:165:18 | PointerSub: ... - ... | 0 | 165 | 166 |
803+
| test.c:165:9:165:18 | CompareLT: ... < ... | test.c:165:13:165:13 | Load: y | >= | test.c:165:9:165:9 | Load: x | 43 | 165 | 166 |
804+
| test.c:165:9:165:18 | CompareLT: ... < ... | test.c:165:13:165:18 | PointerSub: ... - ... | >= | test.c:165:9:165:9 | Load: x | 1 | 165 | 166 |
693805
| test.cpp:18:8:18:12 | CompareNE: (bool)... | test.cpp:18:8:18:10 | Call: call to get | != | test.cpp:18:8:18:12 | Constant: (bool)... | 0 | 19 | 19 |
694806
| test.cpp:18:8:18:12 | CompareNE: (bool)... | test.cpp:18:8:18:12 | Constant: (bool)... | != | test.cpp:18:8:18:10 | Call: call to get | 0 | 19 | 19 |
695807
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | test.cpp:31:12:31:13 | Constant: - ... | 0 | 34 | 34 |

0 commit comments

Comments
 (0)