diff --git a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll index eab96dac19e..c4aed4ddd1e 100644 --- a/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll +++ b/ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll @@ -1219,7 +1219,7 @@ abstract class BarrierGuard extends Node { // Case: a function like "return someBarrierGuard(arg)" // or "return !someBarrierGuard(arg) && otherCond(...)" exists(boolean outcome | - not exists(DataFlow::Node otherRet | otherRet = outp.getEntryNode(fd) | otherRet != ret) and + ret = getUniqueOutputNode(fd, outp) and this.checks(arg.asExpr(), outcome) and // This predicate's contract is (p holds of ret ==> arg is checked), // (and we have (this has outcome ==> arg is checked)) @@ -1234,7 +1234,7 @@ abstract class BarrierGuard extends Node { Function f2, FunctionInput inp2, FunctionOutput outp2, CallNode c, DataFlow::Property outpProp | - not exists(DataFlow::Node otherRet | otherRet = outp.getEntryNode(fd) | otherRet != ret) and + ret = getUniqueOutputNode(fd, outp) and this.guardingFunction(f2, inp2, outp2, outpProp) and c = f2.getACall() and arg = inp2.getNode(c) and @@ -1252,6 +1252,10 @@ abstract class BarrierGuard extends Node { } } +DataFlow::Node getUniqueOutputNode(FuncDecl fd, FunctionOutput outp) { + result = unique(DataFlow::Node n | n = outp.getEntryNode(fd) | n) +} + /** * Holds if `ret` is a data-flow node whose value contributes to the output `res` of `fd`, * and that node may have Boolean value `b`.