Skip to content

Commit 5373e22

Browse files
committed
C++: Improve IRGuads logic for 'unlikely' expressions.
1 parent 7cca213 commit 5373e22

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

Diff for: cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

+22
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,14 @@ private module Cached {
952952
compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, areEqual, value)
953953
}
954954

955+
private predicate isConvertedBool(Instruction instr) {
956+
instr.getResultIRType() instanceof IRBooleanType
957+
or
958+
isConvertedBool(instr.(ConvertInstruction).getUnary())
959+
or
960+
isConvertedBool(instr.(BuiltinExpectCallInstruction).getCondition())
961+
}
962+
955963
/**
956964
* Holds if `op == k` is `areEqual` given that `test` is equal to `value`.
957965
*/
@@ -982,6 +990,20 @@ private module Cached {
982990
k = k1 + k2
983991
)
984992
or
993+
exists(CompareValueNumber cmp, Operand left, Operand right, AbstractValue v |
994+
test = cmp and
995+
cmp.hasOperands(left, right) and
996+
isConvertedBool(left.getDef()) and
997+
int_value(right.getDef()) = 0 and
998+
unary_compares_eq(valueNumberOfOperand(left), op, k, areEqual, v)
999+
|
1000+
cmp instanceof CompareNEValueNumber and
1001+
v = value
1002+
or
1003+
cmp instanceof CompareEQValueNumber and
1004+
v.getDualValue() = value
1005+
)
1006+
or
9851007
unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value)
9861008
}
9871009

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

+6
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,13 @@ astGuardsCompare
263263
| 137 | 0 == 0 when 0 is false |
264264
| 137 | 0 == 1 when 0 is true |
265265
| 146 | ! ... != 0 when ! ... is true |
266+
| 146 | ! ... != 0 when x is false |
266267
| 146 | ! ... != 1 when ! ... is false |
268+
| 146 | ! ... != 1 when x is true |
267269
| 146 | ! ... == 0 when ! ... is false |
270+
| 146 | ! ... == 0 when x is true |
268271
| 146 | ! ... == 1 when ! ... is true |
272+
| 146 | ! ... == 1 when x is false |
269273
| 146 | x != 0 when ! ... is false |
270274
| 146 | x != 0 when x is true |
271275
| 146 | x == 0 when ! ... is true |
@@ -841,6 +845,8 @@ astGuardsEnsure_const
841845
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 |
842846
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 |
843847
| test.c:146:7:146:8 | ! ... | test.c:146:8:146:8 | x | == | 0 | 146 | 147 |
848+
| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 |
849+
| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 |
844850
| test.c:146:8:146:8 | x | test.c:146:8:146:8 | x | == | 0 | 146 | 147 |
845851
| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 151 | 152 |
846852
| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 152 | 152 |

Diff for: cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected

+12
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,13 @@
338338
| 145 | call to __builtin_expect == 0 when call to __builtin_expect is false |
339339
| 145 | call to __builtin_expect == 1 when call to __builtin_expect is true |
340340
| 146 | ! ... != 0 when ! ... is true |
341+
| 146 | ! ... != 0 when x is false |
341342
| 146 | ! ... != 1 when ! ... is false |
343+
| 146 | ! ... != 1 when x is true |
342344
| 146 | ! ... == 0 when ! ... is false |
345+
| 146 | ! ... == 0 when x is true |
343346
| 146 | ! ... == 1 when ! ... is true |
347+
| 146 | ! ... == 1 when x is false |
344348
| 146 | x != 0 when ! ... is false |
345349
| 146 | x != 0 when x is true |
346350
| 146 | x == 0 when ! ... is true |
@@ -350,9 +354,13 @@
350354
| 152 | p == 0 when p is false |
351355
| 152 | p == 1 when p is true |
352356
| 158 | ! ... != 0 when ! ... is true |
357+
| 158 | ! ... != 0 when p is false |
353358
| 158 | ! ... != 1 when ! ... is false |
359+
| 158 | ! ... != 1 when p is true |
354360
| 158 | ! ... == 0 when ! ... is false |
361+
| 158 | ! ... == 0 when p is true |
355362
| 158 | ! ... == 1 when ! ... is true |
363+
| 158 | ! ... == 1 when p is false |
356364
| 158 | p != 0 when ! ... is false |
357365
| 158 | p != 0 when p is true |
358366
| 158 | p == 0 when ! ... is true |
@@ -362,9 +370,13 @@
362370
| 164 | s == 0 when s is false |
363371
| 164 | s == 1 when s is true |
364372
| 170 | ! ... != 0 when ! ... is true |
373+
| 170 | ! ... != 0 when s is false |
365374
| 170 | ! ... != 1 when ! ... is false |
375+
| 170 | ! ... != 1 when s is true |
366376
| 170 | ! ... == 0 when ! ... is false |
377+
| 170 | ! ... == 0 when s is true |
367378
| 170 | ! ... == 1 when ! ... is true |
379+
| 170 | ! ... == 1 when s is false |
368380
| 170 | s != 0 when ! ... is false |
369381
| 170 | s != 0 when s is true |
370382
| 170 | s == 0 when ! ... is true |

Diff for: cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected

+6
Original file line numberDiff line numberDiff line change
@@ -442,18 +442,24 @@ unary
442442
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 |
443443
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 |
444444
| test.c:146:7:146:8 | ! ... | test.c:146:8:146:8 | x | == | 0 | 146 | 147 |
445+
| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 |
446+
| test.c:146:8:146:8 | x | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 |
445447
| test.c:146:8:146:8 | x | test.c:146:8:146:8 | x | == | 0 | 146 | 147 |
446448
| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | 152 | 154 |
447449
| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | == | 1 | 152 | 154 |
448450
| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 |
449451
| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | == | 1 | 158 | 160 |
450452
| test.c:158:8:158:9 | ! ... | test.c:158:9:158:9 | p | == | 0 | 158 | 160 |
453+
| test.c:158:9:158:9 | p | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 |
454+
| test.c:158:9:158:9 | p | test.c:158:8:158:9 | ! ... | == | 1 | 158 | 160 |
451455
| test.c:158:9:158:9 | p | test.c:158:9:158:9 | p | == | 0 | 158 | 160 |
452456
| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | != | 0 | 164 | 166 |
453457
| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | == | 1 | 164 | 166 |
454458
| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 |
455459
| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | == | 1 | 170 | 172 |
456460
| test.c:170:8:170:9 | ! ... | test.c:170:9:170:9 | s | == | 0 | 170 | 172 |
461+
| test.c:170:9:170:9 | s | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 |
462+
| test.c:170:9:170:9 | s | test.c:170:8:170:9 | ! ... | == | 1 | 170 | 172 |
457463
| test.c:170:9:170:9 | s | test.c:170:9:170:9 | s | == | 0 | 170 | 172 |
458464
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
459465
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | 19 | 19 |

0 commit comments

Comments
 (0)