diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 7c34dc43d07..967734f1cfd 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -766,7 +766,7 @@ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) { or exists(PhiNode phiTo | phi != phiTo and - lastRefRedefExt(phi, _, _, phiTo) and + lastRefRedefExt(phi, bb1, i1, phiTo) and nodeTo.(SsaPhiNode).getPhiNode() = phiTo ) ) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.cpp new file mode 100644 index 00000000000..39a9d78e143 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.cpp @@ -0,0 +1,19 @@ +int source(); +void gard_condition_sink(int); +void use(int); +/* + This test checks that we hit the node corresponding to the expression node that wraps `source` + in the condition `source >= 0`. +*/ +void test_guard_condition(int source, bool b) +{ + if (b) { + use(source); + } + + if (source >= 0) { + use(source); + } + + gard_condition_sink(source); // clean +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected new file mode 100644 index 00000000000..8ec8033d086 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.expected @@ -0,0 +1,2 @@ +testFailures +failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql new file mode 100644 index 00000000000..49b650a0793 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/guard-condition-regression-test.ql @@ -0,0 +1,40 @@ +import TestUtilities.InlineExpectationsTest +private import cpp +private import semmle.code.cpp.ir.dataflow.DataFlow +private import semmle.code.cpp.controlflow.IRGuards + +module IRTestAllocationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source.asParameter().getName().matches("source%") and + source.getLocation().getFile().getBaseName() = "guard-condition-regression-test.cpp" + } + + predicate isSink(DataFlow::Node sink) { + exists(FunctionCall call, Expr e | e = call.getAnArgument() | + call.getTarget().getName() = "gard_condition_sink" and + sink.asExpr() = e + ) + } + + predicate isBarrier(DataFlow::Node node) { + exists(GuardCondition gc | node.asExpr() = gc.getAChild*()) + } +} + +private module Flow = DataFlow::Global; + +module GuardConditionRegressionTest implements TestSig { + string getARelevantTag() { result = "guard-condition-regression" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node sink | + Flow::flowTo(sink) and + location = sink.getLocation() and + element = sink.toString() and + tag = "guard-condition-regression" and + value = "" + ) + } +} + +import MakeTest diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected index 0260ed62b05..d4756e8d808 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -5,5 +5,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (test. WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:40,25-33) WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:42,17-25) WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:46,20-28) -failures testFailures +failures