Skip to content

Commit

Permalink
C++: Work around 'getUnconvertedResultExpression' having a result for…
Browse files Browse the repository at this point in the history
… 'CompareNEInstruction's.
  • Loading branch information
MathiasVP committed Nov 20, 2024
1 parent 9fe84eb commit 2dc34c7
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 63 deletions.
34 changes: 34 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,15 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
}
}

bindingset[e]
pragma[inline_late]
private predicate isBoolean(Expr e) {
e.getUnspecifiedType() instanceof BoolType
or
// In C a comparison operation may have an integer type instead of a boolean type.
e instanceof ComparisonOperation
}

/**
* A Boolean condition in the AST that guards one or more basic blocks and has a corresponding IR
* instruction.
Expand Down Expand Up @@ -393,6 +402,26 @@ private class GuardConditionFromIR extends GuardCondition {
exists(Instruction i |
i.getUnconvertedResultExpression() = e and
ir.comparesEq(i.getAUse(), k, areEqual, value)
|
// Consider the following snippet:
// ```
// if(myNumber) { ... }
// ```
// the IR for this looks like:
// ```
// r1(glbal<int>) = VariableAddress[myNumber] :
// r2(int) = Load : &r1
// r3(int) = Constant[0] :
// r4(bool) = CompareNE : r2, r3
// v5(void) = ConditionalBranch : r4
// ```
// In both C and C++, the result of calling `getUnconvertedResultExpression`
// on `r4` is the `myNumber` expression. So users of this predicate would
// conclude that `myNumber = 1` holds on the true branch (since the value
// of `r4` is guaranteed to be `1` on the true branch).
areEqual = false or
not i instanceof CompareNEInstruction or
isBoolean(e)
)
}

Expand All @@ -401,6 +430,11 @@ private class GuardConditionFromIR extends GuardCondition {
i.getUnconvertedResultExpression() = e and
ir.comparesEq(i.getAUse(), k, areEqual, value) and
this.valueControls(block, value)
|
// See the comments on `comparesEq` below for why this is necessary.
areEqual = false or
not i instanceof CompareNEInstruction or
isBoolean(e)
)
}

Expand Down
29 changes: 0 additions & 29 deletions cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ astGuardsCompare
| 18 | call to get != 0 when call to get is true |
| 18 | call to get != 1 when call to get is false |
| 18 | call to get == 0 when call to get is false |
| 18 | call to get == 1 when call to get is true |
| 26 | 0 < x+0 when ... > ... is true |
| 26 | 0 >= x+0 when ... > ... is false |
| 26 | ... > ... != 0 when ... > ... is true |
Expand Down Expand Up @@ -245,22 +244,16 @@ astGuardsCompare
| 126 | 1 != 0 when ... && ... is true |
| 126 | 1 != 1 when 1 is false |
| 126 | 1 == 0 when 1 is false |
| 126 | 1 == 1 when 1 is true |
| 126 | 1 == 1 when ... && ... is true |
| 126 | call to test3_condition != 0 when ... && ... is true |
| 126 | call to test3_condition != 0 when call to test3_condition is true |
| 126 | call to test3_condition != 1 when call to test3_condition is false |
| 126 | call to test3_condition == 0 when call to test3_condition is false |
| 126 | call to test3_condition == 1 when ... && ... is true |
| 126 | call to test3_condition == 1 when call to test3_condition is true |
| 131 | b != 0 when b is true |
| 131 | b != 1 when b is false |
| 131 | b == 0 when b is false |
| 131 | b == 1 when b is true |
| 137 | 0 != 0 when 0 is true |
| 137 | 0 != 1 when 0 is false |
| 137 | 0 == 0 when 0 is false |
| 137 | 0 == 1 when 0 is true |
| 146 | ! ... != 0 when ! ... is true |
| 146 | ! ... != 1 when ! ... is false |
| 146 | ! ... == 0 when ! ... is false |
Expand All @@ -271,14 +264,10 @@ astGuardsCompare
| 152 | x != 0 when x is true |
| 152 | x != 1 when x is false |
| 152 | x == 0 when x is false |
| 152 | x == 1 when ... && ... is true |
| 152 | x == 1 when x is true |
| 152 | y != 0 when ... && ... is true |
| 152 | y != 0 when y is true |
| 152 | y != 1 when y is false |
| 152 | y == 0 when y is false |
| 152 | y == 1 when ... && ... is true |
| 152 | y == 1 when y is true |
| 156 | ... + ... != x+0 when ... == ... is false |
| 156 | ... + ... == x+0 when ... == ... is true |
| 156 | ... == ... != 0 when ... == ... is true |
Expand Down Expand Up @@ -340,7 +329,6 @@ astGuardsCompare
| 181 | x != 0 when x is true |
| 181 | x != 1 when x is false |
| 181 | x == 0 when x is false |
| 181 | x == 1 when x is true |
astGuardsControl
| test.c:7:9:7:13 | ... > ... | false | 10 | 11 |
| test.c:7:9:7:13 | ... > ... | true | 7 | 9 |
Expand Down Expand Up @@ -819,34 +807,20 @@ astGuardsEnsure_const
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 126 | 126 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 131 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 |
| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | == | 1 | 131 | 132 |
| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | != | 1 | 142 | 136 |
| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 |
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 |
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 |
| test.c:146:7:146:8 | ! ... | test.c:146:8:146:8 | x | == | 0 | 146 | 147 |
| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 151 | 152 |
| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | != | 0 | 152 | 152 |
| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | == | 1 | 151 | 152 |
| test.c:152:10:152:10 | x | test.c:152:10:152:10 | x | == | 1 | 152 | 152 |
| test.c:152:10:152:15 | ... && ... | test.c:152:10:152:10 | x | != | 0 | 151 | 152 |
| test.c:152:10:152:15 | ... && ... | test.c:152:10:152:10 | x | == | 1 | 151 | 152 |
| test.c:152:10:152:15 | ... && ... | test.c:152:15:152:15 | y | != | 0 | 151 | 152 |
| test.c:152:10:152:15 | ... && ... | test.c:152:15:152:15 | y | == | 1 | 151 | 152 |
| test.c:152:15:152:15 | y | test.c:152:15:152:15 | y | != | 0 | 151 | 152 |
| test.c:152:15:152:15 | y | test.c:152:15:152:15 | y | == | 1 | 151 | 152 |
| test.c:156:9:156:19 | ... == ... | test.c:156:9:156:19 | ... == ... | != | 0 | 156 | 157 |
| test.c:156:9:156:19 | ... == ... | test.c:156:9:156:19 | ... == ... | == | 1 | 156 | 157 |
| test.c:159:9:159:19 | ... == ... | test.c:159:9:159:19 | ... == ... | != | 0 | 159 | 160 |
Expand All @@ -865,10 +839,7 @@ astGuardsEnsure_const
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | != | 0 | 186 | 180 |
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | != | 1 | 183 | 184 |
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 0 | 183 | 184 |
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 1 | 181 | 182 |
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 1 | 186 | 180 |
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | 19 | 19 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
| 18 | call to get != 0 when call to get is true |
| 18 | call to get != 1 when call to get is false |
| 18 | call to get == 0 when call to get is false |
| 18 | call to get == 1 when call to get is true |
| 26 | 0 < x+0 when ... > ... is true |
| 26 | 0 >= x+0 when ... > ... is false |
| 26 | ... > ... != 0 when ... > ... is true |
Expand Down Expand Up @@ -186,7 +185,6 @@
| 93 | c != 0 when c is true |
| 93 | c != 1 when c is false |
| 93 | c == 0 when c is false |
| 93 | c == 1 when c is true |
| 94 | 0 != x+0 when ... != ... is true |
| 94 | 0 == x+0 when ... != ... is false |
| 94 | ... != ... != 0 when ... != ... is true |
Expand All @@ -199,8 +197,6 @@
| 94 | x == 0+0 when ... != ... is false |
| 99 | f != 0 when f is true |
| 99 | f != 1 when f is false |
| 99 | f == 0 when f is false |
| 99 | f == 1 when f is true |
| 102 | 10 < j+1 when ... < ... is false |
| 102 | 10 >= j+1 when ... < ... is true |
| 102 | ... < ... != 0 when ... < ... is true |
Expand Down Expand Up @@ -277,14 +273,10 @@
| 126 | 1 != 0 when ... && ... is true |
| 126 | 1 != 1 when 1 is false |
| 126 | 1 == 0 when 1 is false |
| 126 | 1 == 1 when 1 is true |
| 126 | 1 == 1 when ... && ... is true |
| 126 | call to test3_condition != 0 when ... && ... is true |
| 126 | call to test3_condition != 0 when call to test3_condition is true |
| 126 | call to test3_condition != 1 when call to test3_condition is false |
| 126 | call to test3_condition == 0 when call to test3_condition is false |
| 126 | call to test3_condition == 1 when ... && ... is true |
| 126 | call to test3_condition == 1 when call to test3_condition is true |
| 131 | ... + ... != a+0 when call to __builtin_expect is false |
| 131 | ... + ... == a+0 when call to __builtin_expect is true |
| 131 | ... == ... != 0 when call to __builtin_expect is true |
Expand All @@ -299,12 +291,10 @@
| 131 | b != 1 when b is false |
| 131 | b != a+-42 when call to __builtin_expect is false |
| 131 | b == 0 when b is false |
| 131 | b == 1 when b is true |
| 131 | b == a+-42 when call to __builtin_expect is true |
| 131 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 131 | call to __builtin_expect != 1 when call to __builtin_expect is false |
| 131 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 131 | call to __builtin_expect == 1 when call to __builtin_expect is true |
| 135 | ... != ... != 0 when call to __builtin_expect is true |
| 135 | ... != ... != 1 when call to __builtin_expect is false |
| 135 | ... != ... == 0 when call to __builtin_expect is false |
Expand All @@ -320,11 +310,9 @@
| 135 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 135 | call to __builtin_expect != 1 when call to __builtin_expect is false |
| 135 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 135 | call to __builtin_expect == 1 when call to __builtin_expect is true |
| 137 | 0 != 0 when 0 is true |
| 137 | 0 != 1 when 0 is false |
| 137 | 0 == 0 when 0 is false |
| 137 | 0 == 1 when 0 is true |
| 141 | 42 != a+0 when call to __builtin_expect is false |
| 141 | 42 == a+0 when call to __builtin_expect is true |
| 141 | ... == ... != 0 when call to __builtin_expect is true |
Expand All @@ -338,7 +326,6 @@
| 141 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 141 | call to __builtin_expect != 1 when call to __builtin_expect is false |
| 141 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 141 | call to __builtin_expect == 1 when call to __builtin_expect is true |
| 145 | 42 != a+0 when call to __builtin_expect is true |
| 145 | 42 == a+0 when call to __builtin_expect is false |
| 145 | ... != ... != 0 when call to __builtin_expect is true |
Expand All @@ -352,7 +339,6 @@
| 145 | call to __builtin_expect != 0 when call to __builtin_expect is true |
| 145 | call to __builtin_expect != 1 when call to __builtin_expect is false |
| 145 | call to __builtin_expect == 0 when call to __builtin_expect is false |
| 145 | call to __builtin_expect == 1 when call to __builtin_expect is true |
| 146 | ! ... != 0 when ! ... is true |
| 146 | ! ... != 1 when ! ... is false |
| 146 | ! ... == 0 when ! ... is false |
Expand All @@ -362,7 +348,6 @@
| 152 | p != 0 when p is true |
| 152 | p != 1 when p is false |
| 152 | p == 0 when p is false |
| 152 | p == 1 when p is true |
| 158 | ! ... != 0 when ! ... is true |
| 158 | ! ... != 1 when ! ... is false |
| 158 | ! ... == 0 when ! ... is false |
Expand All @@ -372,7 +357,6 @@
| 164 | s != 0 when s is true |
| 164 | s != 1 when s is false |
| 164 | s == 0 when s is false |
| 164 | s == 1 when s is true |
| 170 | ! ... != 0 when ! ... is true |
| 170 | ! ... != 1 when ! ... is false |
| 170 | ! ... == 0 when ! ... is false |
Expand Down
18 changes: 0 additions & 18 deletions cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected
Original file line number Diff line number Diff line change
Expand Up @@ -424,36 +424,24 @@ unary
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 126 | 126 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 131 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | != | 0 | 131 | 132 |
| test.c:131:7:131:7 | b | test.c:131:7:131:7 | b | == | 1 | 131 | 132 |
| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | != | 1 | 142 | 136 |
| test.c:137:7:137:7 | 0 | test.c:137:7:137:7 | 0 | == | 0 | 142 | 136 |
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | != | 0 | 146 | 147 |
| test.c:146:7:146:8 | ! ... | test.c:146:7:146:8 | ! ... | == | 1 | 146 | 147 |
| test.c:146:7:146:8 | ! ... | test.c:146:8:146:8 | x | == | 0 | 146 | 147 |
| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | != | 0 | 152 | 154 |
| test.c:152:8:152:8 | p | test.c:152:8:152:8 | p | == | 1 | 152 | 154 |
| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | != | 0 | 158 | 160 |
| test.c:158:8:158:9 | ! ... | test.c:158:8:158:9 | ! ... | == | 1 | 158 | 160 |
| test.c:158:8:158:9 | ! ... | test.c:158:9:158:9 | p | == | 0 | 158 | 160 |
| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | != | 0 | 164 | 166 |
| test.c:164:8:164:8 | s | test.c:164:8:164:8 | s | == | 1 | 164 | 166 |
| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | != | 0 | 170 | 172 |
| test.c:170:8:170:9 | ! ... | test.c:170:8:170:9 | ! ... | == | 1 | 170 | 172 |
| test.c:170:8:170:9 | ! ... | test.c:170:9:170:9 | s | == | 0 | 170 | 172 |
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | 19 | 19 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
Expand All @@ -477,9 +465,7 @@ unary
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 |
| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | 93 | 94 |
| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | == | 1 | 93 | 94 |
| test.cpp:99:6:99:6 | f | test.cpp:99:6:99:6 | f | != | 0 | 99 | 100 |
| test.cpp:99:6:99:6 | f | test.cpp:99:6:99:6 | f | == | 1 | 99 | 100 |
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | != | 0 | 105 | 106 |
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:14 | ... != ... | == | 1 | 105 | 106 |
| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:14 | ... != ... | != | 0 | 111 | 112 |
Expand All @@ -495,20 +481,16 @@ unary
| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | != | 1 | 125 | 125 |
| test.cpp:125:14:125:17 | call to safe | test.cpp:125:14:125:17 | call to safe | == | 0 | 125 | 125 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | != | 0 | 131 | 132 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:6:131:21 | call to __builtin_expect | == | 1 | 131 | 132 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:33 | ... == ... | != | 0 | 131 | 132 |
| test.cpp:131:6:131:21 | call to __builtin_expect | test.cpp:131:23:131:33 | ... == ... | == | 1 | 131 | 132 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | != | 0 | 135 | 136 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:6:135:21 | call to __builtin_expect | == | 1 | 135 | 136 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:33 | ... != ... | != | 0 | 135 | 136 |
| test.cpp:135:6:135:21 | call to __builtin_expect | test.cpp:135:23:135:33 | ... != ... | == | 1 | 135 | 136 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | != | 0 | 141 | 142 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:6:141:21 | call to __builtin_expect | == | 1 | 141 | 142 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:23 | a | == | 42 | 141 | 142 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:29 | ... == ... | != | 0 | 141 | 142 |
| test.cpp:141:6:141:21 | call to __builtin_expect | test.cpp:141:23:141:29 | ... == ... | == | 1 | 141 | 142 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | != | 0 | 145 | 146 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:6:145:21 | call to __builtin_expect | == | 1 | 145 | 146 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:23 | a | != | 42 | 145 | 146 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:29 | ... != ... | != | 0 | 145 | 146 |
| test.cpp:145:6:145:21 | call to __builtin_expect | test.cpp:145:23:145:29 | ... != ... | == | 1 | 145 | 146 |

0 comments on commit 2dc34c7

Please sign in to comment.