diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index b836f12c96f4..76a1299cb536 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -994,6 +994,18 @@ private module Cached { ) or unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value) + or + exists(BinaryLogicalOperation logical, Expr operand, boolean b | + test.getAnInstruction().getUnconvertedResultExpression() = logical and + op.getDef().getUnconvertedResultExpression() = operand and + logical.impliesValue(operand, b, value.(BooleanValue).getValue()) + | + k = 1 and + areEqual = b + or + k = 0 and + areEqual = b.booleanNot() + ) } /** Rearrange various simple comparisons into `left == right + k` form. */ diff --git a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected index a56d8964c095..48bfb7aaf966 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/Guards.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/Guards.expected @@ -69,3 +69,11 @@ | test.cpp:168:8:168:8 | b | | test.cpp:176:7:176:8 | ! ... | | test.cpp:176:8:176:8 | c | +| test.cpp:182:6:182:16 | ! ... | +| test.cpp:182:8:182:9 | b1 | +| test.cpp:182:8:182:15 | ... && ... | +| test.cpp:182:14:182:15 | b2 | +| test.cpp:193:6:193:16 | ! ... | +| test.cpp:193:8:193:9 | b1 | +| test.cpp:193:8:193:15 | ... \|\| ... | +| test.cpp:193:14:193:15 | b2 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected index f2ce7f611f39..2ff93603a267 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected @@ -545,8 +545,12 @@ | 182 | ! ... == 1 when ... && ... is false | | 182 | ... && ... != 0 when ! ... is false | | 182 | ... && ... != 0 when ... && ... is true | +| 182 | ... && ... != 1 when ! ... is true | +| 182 | ... && ... != 1 when ... && ... is false | | 182 | ... && ... == 0 when ! ... is true | | 182 | ... && ... == 0 when ... && ... is false | +| 182 | ... && ... == 1 when ! ... is false | +| 182 | ... && ... == 1 when ... && ... is true | | 182 | ... < ... != 0 when ... && ... is true | | 182 | ... < ... != 0 when ... < ... is true | | 182 | ... < ... != 1 when ... < ... is false | @@ -559,6 +563,22 @@ | 182 | ... >= ... == 0 when ... >= ... is false | | 182 | ... >= ... == 1 when ... && ... is true | | 182 | ... >= ... == 1 when ... >= ... is true | +| 182 | b1 != 0 when ! ... is false | +| 182 | b1 != 0 when ... && ... is true | +| 182 | b1 != 0 when b1 is true | +| 182 | b1 != 1 when b1 is false | +| 182 | b1 == 0 when b1 is false | +| 182 | b1 == 1 when ! ... is false | +| 182 | b1 == 1 when ... && ... is true | +| 182 | b1 == 1 when b1 is true | +| 182 | b2 != 0 when ! ... is false | +| 182 | b2 != 0 when ... && ... is true | +| 182 | b2 != 0 when b2 is true | +| 182 | b2 != 1 when b2 is false | +| 182 | b2 == 0 when b2 is false | +| 182 | b2 == 1 when ! ... is false | +| 182 | b2 == 1 when ... && ... is true | +| 182 | b2 == 1 when b2 is true | | 182 | foo < 1.0+0 when ... && ... is true | | 182 | foo < 1.0+0 when ... < ... is true | | 182 | foo < 9.999999999999999547e-07+0 when ... >= ... is false | @@ -577,6 +597,38 @@ | 190 | c != 0 when c is true | | 190 | c == 0 when ! ... is true | | 190 | c == 0 when c is false | +| 193 | ! ... != 0 when ! ... is true | +| 193 | ! ... != 0 when ... \|\| ... is false | +| 193 | ! ... != 1 when ! ... is false | +| 193 | ! ... != 1 when ... \|\| ... is true | +| 193 | ! ... == 0 when ! ... is false | +| 193 | ! ... == 0 when ... \|\| ... is true | +| 193 | ! ... == 1 when ! ... is true | +| 193 | ! ... == 1 when ... \|\| ... is false | +| 193 | ... \|\| ... != 0 when ! ... is false | +| 193 | ... \|\| ... != 0 when ... \|\| ... is true | +| 193 | ... \|\| ... != 1 when ! ... is true | +| 193 | ... \|\| ... != 1 when ... \|\| ... is false | +| 193 | ... \|\| ... == 0 when ! ... is true | +| 193 | ... \|\| ... == 0 when ... \|\| ... is false | +| 193 | ... \|\| ... == 1 when ! ... is false | +| 193 | ... \|\| ... == 1 when ... \|\| ... is true | +| 193 | b1 != 0 when b1 is true | +| 193 | b1 != 1 when ! ... is true | +| 193 | b1 != 1 when ... \|\| ... is false | +| 193 | b1 != 1 when b1 is false | +| 193 | b1 == 0 when ! ... is true | +| 193 | b1 == 0 when ... \|\| ... is false | +| 193 | b1 == 0 when b1 is false | +| 193 | b1 == 1 when b1 is true | +| 193 | b2 != 0 when b2 is true | +| 193 | b2 != 1 when ! ... is true | +| 193 | b2 != 1 when ... \|\| ... is false | +| 193 | b2 != 1 when b2 is false | +| 193 | b2 == 0 when ! ... is true | +| 193 | b2 == 0 when ... \|\| ... is false | +| 193 | b2 == 0 when b2 is false | +| 193 | b2 == 1 when b2 is true | | 198 | ! ... != 0 when ! ... is true | | 198 | ! ... != 0 when b is false | | 198 | ! ... != 1 when ! ... is false | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index 2857bdf511bf..cee020adadd9 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -130,3 +130,19 @@ | test.cpp:168:8:168:8 | b | false | 168 | 170 | | test.cpp:176:7:176:8 | ! ... | true | 176 | 178 | | test.cpp:176:8:176:8 | c | false | 176 | 178 | +| test.cpp:182:6:182:16 | ! ... | false | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | true | 182 | 184 | +| test.cpp:182:8:182:9 | b1 | true | 181 | 182 | +| test.cpp:182:8:182:9 | b1 | true | 182 | 182 | +| test.cpp:182:8:182:15 | ... && ... | false | 182 | 184 | +| test.cpp:182:8:182:15 | ... && ... | true | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | true | 185 | 188 | +| test.cpp:182:14:182:15 | b2 | true | 181 | 182 | +| test.cpp:193:6:193:16 | ! ... | false | 197 | 199 | +| test.cpp:193:6:193:16 | ! ... | true | 193 | 196 | +| test.cpp:193:8:193:9 | b1 | false | 192 | 193 | +| test.cpp:193:8:193:9 | b1 | false | 193 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | false | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | false | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | true | 197 | 199 | +| test.cpp:193:14:193:15 | b2 | false | 192 | 193 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index 73a809b3175c..288b49ceb687 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -636,3 +636,79 @@ unary | test.cpp:176:8:176:8 | c | test.cpp:176:7:176:8 | ! ... | == | 1 | 176 | 178 | | test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | != | 1 | 176 | 178 | | test.cpp:176:8:176:8 | c | test.cpp:176:8:176:8 | c | == | 0 | 176 | 178 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 0 | 182 | 184 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:6:182:16 | ! ... | == | 1 | 182 | 184 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | != | 0 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:9 | b1 | == | 1 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | 182 | 184 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | 182 | 184 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | != | 0 | 185 | 188 | +| test.cpp:182:6:182:16 | ! ... | test.cpp:182:14:182:15 | b2 | == | 1 | 185 | 188 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | 181 | 182 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | != | 0 | 182 | 182 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | 181 | 182 | +| test.cpp:182:8:182:9 | b1 | test.cpp:182:8:182:9 | b1 | == | 1 | 182 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 0 | 182 | 184 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | != | 1 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 0 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:6:182:16 | ! ... | == | 1 | 182 | 184 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | != | 0 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:9 | b1 | == | 1 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 0 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | != | 1 | 182 | 184 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 0 | 182 | 184 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:8:182:15 | ... && ... | == | 1 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | != | 0 | 185 | 188 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | 181 | 182 | +| test.cpp:182:8:182:15 | ... && ... | test.cpp:182:14:182:15 | b2 | == | 1 | 185 | 188 | +| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | != | 0 | 181 | 182 | +| test.cpp:182:14:182:15 | b2 | test.cpp:182:14:182:15 | b2 | == | 1 | 181 | 182 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | != | 1 | 197 | 199 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 0 | 197 | 199 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | 197 | 199 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | 197 | 199 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | != | 1 | 193 | 196 | +| test.cpp:193:6:193:16 | ! ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | 192 | 193 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 193 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | 192 | 193 | +| test.cpp:193:8:193:9 | b1 | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 0 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | != | 1 | 197 | 199 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 0 | 197 | 199 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:6:193:16 | ! ... | == | 1 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | != | 1 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:9 | b1 | == | 0 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 0 | 197 | 199 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | != | 1 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 0 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:8:193:15 | ... \|\| ... | == | 1 | 197 | 199 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | != | 1 | 193 | 196 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 | +| test.cpp:193:8:193:15 | ... \|\| ... | test.cpp:193:14:193:15 | b2 | == | 0 | 193 | 196 | +| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | != | 1 | 192 | 193 | +| test.cpp:193:14:193:15 | b2 | test.cpp:193:14:193:15 | b2 | == | 0 | 192 | 193 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/test.cpp b/cpp/ql/test/library-tests/controlflow/guards/test.cpp index 3bdcdcc01ff5..7349671633d4 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/guards/test.cpp @@ -176,4 +176,26 @@ void test_with_negated_binary_relational(int a, int b) { if (!c) { } +} + +void test_logical_and(bool b1, bool b2) { + if(!(b1 && b2)) { + use(b1); + use(b2); + } else { + // b1 = true and b2 = true + use(b1); + use(b2); + } +} + +void test_logical_or(bool b1, bool b2) { + if(!(b1 || b2)) { + // b1 = false and b2 = false + use(b1); + use(b2); + } else { + use(b1); + use(b2); + } } \ No newline at end of file