diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll index 824e5886c62..211be2aa432 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll @@ -684,24 +684,26 @@ final class GuardCondition = GuardConditionImpl; */ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof Cpp::BinaryLogicalOperation { + GuardConditionImpl l; + GuardConditionImpl r; + + GuardConditionFromBinaryLogicalOperator() { + super.getLeftOperand() = l and + super.getRightOperand() = r + } + override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) { - exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | - this = binop and - lhs = binop.getLeftOperand() and - rhs = binop.getRightOperand() and - lhs.valueControls(controlled, v) and - rhs.valueControls(controlled, v) - ) + // `l || r` does not control `r` even though `l` does. + not r.(Cpp::Expr).getBasicBlock() = controlled and + l.valueControls(controlled, v) + or + r.valueControls(controlled, v) } override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) { - exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs | - this = binop and - lhs = binop.getLeftOperand() and - rhs = binop.getRightOperand() and - lhs.valueControlsEdge(pred, succ, v) and - rhs.valueControlsEdge(pred, succ, v) - ) + l.valueControlsEdge(pred, succ, v) + or + r.valueControlsEdge(pred, succ, v) } pragma[nomagic] diff --git a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected index 747564a745e..62cecc05915 100644 --- a/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected +++ b/cpp/ql/test/library-tests/controlflow/guards-ir/tests.expected @@ -384,7 +384,9 @@ astGuardsControl | test.c:126:7:126:7 | 1 | true | 131 | 132 | | test.c:126:7:126:7 | 1 | true | 134 | 123 | | test.c:126:7:126:28 | ... && ... | true | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | true | 131 | 131 | | test.c:126:7:126:28 | ... && ... | true | 131 | 132 | +| test.c:126:7:126:28 | ... && ... | true | 134 | 123 | | test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 | | test.c:126:12:126:26 | call to test3_condition | true | 131 | 132 | | test.c:131:7:131:7 | b | true | 131 | 132 | @@ -787,13 +789,21 @@ astGuardsEnsure_const | 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 | != | 0 | 131 | 131 | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 | | 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:7:126:7 | 1 | == | 1 | 131 | 131 | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 | | 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 | != | 0 | 131 | 131 | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 134 | 123 | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 131 | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 132 | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 134 | 123 | | 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 | != | 0 | 131 | 132 | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected index 040173a2a4b..947fffd95f6 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsControl.expected @@ -105,9 +105,13 @@ | test.c:126:7:126:7 | 1 | true | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:7 | 1 | true | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | not 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | not 0 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | true | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | true | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:28 | ... && ... | true | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | true | test.c:134:1:123:10 | return ... | | test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:126:31:128:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:131:10:132:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | true | test.c:126:31:128:16 | { ... } | diff --git a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected index a1d3a37bea2..5a364e3deaa 100644 --- a/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected +++ b/cpp/ql/test/library-tests/controlflow/guards/GuardsEnsure.expected @@ -758,13 +758,21 @@ unary | test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } | | test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:134:1:123:10 | return ... | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:3:131:7 | if (...) ... | | test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:10:132:16 | { ... } | +| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:134:1:123:10 | return ... | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } | | test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } |